home *** CD-ROM | disk | FTP | other *** search
/ TeX 1995 July / TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO / graphics / gnuplot / setshow.c < prev    next >
C/C++ Source or Header  |  1993-09-15  |  76KB  |  3,023 lines

  1. static char *RCSid = "$Id: setshow.c%v 3.50.1.11 1993/08/10 03:55:03 woo Exp $";
  2.  
  3.  
  4. /* GNUPLOT - setshow.c */
  5. /*
  6.  * Copyright (C) 1986 - 1993   Thomas Williams, Colin Kelley
  7.  *
  8.  * Permission to use, copy, and distribute this software and its
  9.  * documentation for any purpose with or without fee is hereby granted, 
  10.  * provided that the above copyright notice appear in all copies and 
  11.  * that both that copyright notice and this permission notice appear 
  12.  * in supporting documentation.
  13.  *
  14.  * Permission to modify the software is granted, but not the right to
  15.  * distribute the modified code.  Modifications are to be distributed 
  16.  * as patches to released version.
  17.  *  
  18.  * This software is provided "as is" without express or implied warranty.
  19.  * 
  20.  *
  21.  * AUTHORS
  22.  * 
  23.  *   Original Software:
  24.  *     Thomas Williams,  Colin Kelley.
  25.  * 
  26.  *   Gnuplot 2.0 additions:
  27.  *       Russell Lang, Dave Kotz, John Campbell.
  28.  *
  29.  *   Gnuplot 3.0 additions:
  30.  *       Gershon Elber and many others.
  31.  *
  32.  * 19 September 1992  Lawrence Crowl  (crowl@cs.orst.edu)
  33.  * Added user-specified bases for log scaling.
  34.  * 
  35.  * There is a mailing list for gnuplot users. Note, however, that the
  36.  * newsgroup 
  37.  *    comp.graphics.gnuplot 
  38.  * is identical to the mailing list (they
  39.  * both carry the same set of messages). We prefer that you read the
  40.  * messages through that newsgroup, to subscribing to the mailing list.
  41.  * (If you can read that newsgroup, and are already on the mailing list,
  42.  * please send a message info-gnuplot-request@dartmouth.edu, asking to be
  43.  * removed from the mailing list.)
  44.  *
  45.  * The address for mailing to list members is
  46.  *       info-gnuplot@dartmouth.edu
  47.  * and for mailing administrative requests is 
  48.  *       info-gnuplot-request@dartmouth.edu
  49.  * The mailing list for bug reports is 
  50.  *       bug-gnuplot@dartmouth.edu
  51.  * The list of those interested in beta-test versions is
  52.  *       info-gnuplot-beta@dartmouth.edu
  53.  */
  54.  
  55. #include <stdio.h>
  56. #include <math.h>
  57. #include "plot.h"
  58. #include "setshow.h"
  59.  
  60. #define DEF_FORMAT   "%g"    /* default format for tic mark labels */
  61. #define SIGNIF (0.01)        /* less than one hundredth of a tic mark */
  62.  
  63. /*
  64.  * global variables to hold status of 'set' options
  65.  *
  66.  */
  67. TBOOLEAN        autoscale_r    = TRUE;
  68. TBOOLEAN        autoscale_t    = TRUE;
  69. TBOOLEAN        autoscale_u    = TRUE;
  70. TBOOLEAN        autoscale_v    = TRUE;
  71. TBOOLEAN        autoscale_x    = TRUE;
  72. TBOOLEAN        autoscale_y    = TRUE;
  73. TBOOLEAN        autoscale_z    = TRUE;
  74. TBOOLEAN        autoscale_lt    = TRUE;
  75. TBOOLEAN        autoscale_lu    = TRUE;
  76. TBOOLEAN        autoscale_lv    = TRUE;
  77. TBOOLEAN        autoscale_lx    = TRUE;
  78. TBOOLEAN        autoscale_ly    = TRUE;
  79. TBOOLEAN        autoscale_lz    = TRUE;
  80. double            boxwidth    = -1.0; /* box width (automatic) */
  81. TBOOLEAN         clip_points    = FALSE;
  82. TBOOLEAN         clip_lines1    = TRUE;
  83. TBOOLEAN         clip_lines2    = FALSE;
  84. TBOOLEAN        draw_border    = TRUE;
  85. TBOOLEAN        draw_surface    = TRUE;
  86. TBOOLEAN        timedate    = FALSE;
  87. char            dummy_var[MAX_NUM_VAR][MAX_ID_LEN+1] = { "x", "y" };
  88. char            xformat[MAX_ID_LEN+1] = DEF_FORMAT;
  89. char            yformat[MAX_ID_LEN+1] = DEF_FORMAT;
  90. char            zformat[MAX_ID_LEN+1] = DEF_FORMAT;
  91. enum PLOT_STYLE        data_style    = POINTSTYLE;
  92. enum PLOT_STYLE        func_style    = LINES;
  93. TBOOLEAN        grid        = FALSE;
  94. int            key        = -1;    /* default position */
  95. double            key_x;
  96. double            key_y;    /* user specified position for key */
  97. double            key_z;
  98. TBOOLEAN        is_log_x    = FALSE;
  99. TBOOLEAN        is_log_y    = FALSE;
  100. TBOOLEAN        is_log_z    = FALSE;
  101. double            base_log_x    = 0.0;
  102. double            base_log_y    = 0.0;
  103. double            base_log_z    = 0.0;
  104. double            log_base_log_x    = 0.0;
  105. double            log_base_log_y    = 0.0;
  106. double            log_base_log_z    = 0.0;
  107. FILE*            outfile;
  108. char            outstr[MAX_ID_LEN+1] = "STDOUT";
  109. TBOOLEAN        parametric    = FALSE;
  110. TBOOLEAN        polar        = FALSE;
  111. TBOOLEAN        hidden3d    = FALSE;
  112. TBOOLEAN        label_contours    = TRUE; /* different linestyles are used for contours when set */
  113. int            angles_format    = ANGLES_RADIANS;
  114. int            mapping3d    = MAP3D_CARTESIAN;
  115. int            samples        = SAMPLES; /* samples is always equal to samples_1 */
  116. int            samples_1    = SAMPLES;
  117. int            samples_2    = SAMPLES;
  118. int            iso_samples_1    = ISO_SAMPLES;
  119. int            iso_samples_2    = ISO_SAMPLES;
  120. float            xsize        = 1.0;  /* scale factor for size */
  121. float            ysize        = 1.0;  /* scale factor for size */
  122. float            zsize        = 1.0;  /* scale factor for size */
  123. float            surface_rot_z   = 30.0; /* Default 3d transform. */
  124. float            surface_rot_x   = 60.0;
  125. float            surface_scale   = 1.0;
  126. float            surface_zscale  = 1.0;
  127. int            term        = 0;        /* unknown term is 0 */
  128. char            term_options[MAX_LINE_LEN+1] = "";
  129. char            title[MAX_LINE_LEN+1] = "";
  130. char            xlabel[MAX_LINE_LEN+1] = "";
  131. char            ylabel[MAX_LINE_LEN+1] = "";
  132. char            zlabel[MAX_LINE_LEN+1] = "";
  133. int            time_xoffset    = 0;
  134. int            time_yoffset    = 0;
  135. int            title_xoffset    = 0;
  136. int            title_yoffset    = 0;
  137. int            xlabel_xoffset    = 0;
  138. int            xlabel_yoffset    = 0;
  139. int            ylabel_xoffset    = 0;
  140. int            ylabel_yoffset    = 0;
  141. int            zlabel_xoffset    = 0;
  142. int            zlabel_yoffset    = 0;
  143. double            rmin        = -0.0;
  144. double            rmax        =  10.0;
  145. double            tmin        = -5.0;
  146. double            tmax        =  5.0;
  147. double            umin        = -5.0;
  148. double            umax        = 5.0;
  149. double            vmin        = -5.0;
  150. double            vmax        = 5.0;
  151. double            xmin        = -10.0;
  152. double            xmax        = 10.0;
  153. double            ymin        = -10.0;
  154. double            ymax        = 10.0;
  155. double            zmin        = -10.0;
  156. double            zmax        = 10.0;
  157. double            loff        = 0.0;
  158. double            roff        = 0.0;
  159. double            toff        = 0.0;
  160. double            boff        = 0.0;
  161. int            draw_contour    = CONTOUR_NONE;
  162. int            contour_pts    = 5;
  163. int            contour_kind    = CONTOUR_KIND_LINEAR;
  164. int            contour_order    = 4;
  165. int            contour_levels    = 5;
  166. double            zero        = ZERO;    /* zero threshold, not 0! */
  167. int            levels_kind    = LEVELS_AUTO;
  168. double            levels_list[MAX_DISCRETE_LEVELS];  /* storage for z levels to draw contours at */
  169.  
  170. int            dgrid3d_row_fineness = 10;
  171. int            dgrid3d_col_fineness = 10;
  172. int            dgrid3d_norm_value = 1;
  173. TBOOLEAN        dgrid3d        = FALSE;
  174.  
  175. TBOOLEAN         xzeroaxis    = TRUE;
  176. TBOOLEAN         yzeroaxis    = TRUE;
  177.  
  178. TBOOLEAN         xtics        = TRUE;
  179. TBOOLEAN         ytics        = TRUE;
  180. TBOOLEAN         ztics        = TRUE;
  181.  
  182. float             ticslevel    = 0.5;
  183.  
  184. struct ticdef        xticdef        = {TIC_COMPUTED};
  185. struct ticdef        yticdef        = {TIC_COMPUTED};
  186. struct ticdef        zticdef        = {TIC_COMPUTED};
  187.  
  188. TBOOLEAN        tic_in        = TRUE;
  189.  
  190. struct text_label     *first_label    = NULL;
  191. struct arrow_def     *first_arrow    = NULL;
  192.  
  193. /*** other things we need *****/
  194. #ifdef _Windows
  195. #include <string.h>
  196. #else
  197. #if !defined(ATARI) && !defined (AMIGA_SC_6_1)
  198. extern char *strcpy(),*strcat();
  199. extern int      strlen();
  200. #endif
  201. #endif
  202.  
  203. #if defined(unix) || defined(PIPES)
  204. extern FILE *popen();
  205. #endif
  206.  
  207. /* input data, parsing variables */
  208. extern struct lexical_unit token[];
  209. extern char input_line[];
  210. extern int num_tokens, c_token;
  211. extern TBOOLEAN interactive;    /* from plot.c */
  212.  
  213. extern char replot_line[];
  214. extern struct udvt_entry *first_udv;
  215. extern TBOOLEAN is_3d_plot;
  216.  
  217. extern double magnitude(),real();
  218. extern struct value *const_express();
  219.  
  220. #ifdef _Windows
  221. extern FILE * open_printer();
  222. extern void close_printer();
  223. #endif
  224.  
  225. /******** Local functions ********/
  226. static void set_xyzlabel();
  227. static void set_label();
  228. static void set_nolabel();
  229. static void set_arrow();
  230. static void set_noarrow();
  231. static void load_tics();
  232. static void load_tic_user();
  233. static void free_marklist();
  234. static void load_tic_series();
  235. static void load_offsets();
  236.  
  237. static void show_style(), show_range(), show_zero(), show_border(), show_dgrid3d();
  238. static void show_offsets(), show_output(), show_samples(), show_isosamples();
  239. static void show_view(), show_size(), show_title(), show_xlabel();
  240. static void show_angles(), show_boxwidth();
  241. static void show_ylabel(), show_zlabel(), show_xzeroaxis(), show_yzeroaxis();
  242. static void show_label(), show_arrow(), show_grid(), show_key();
  243. static void show_polar(), show_parametric(), show_tics(), show_ticdef();
  244. static void show_time(), show_term(), show_plot(), show_autoscale(), show_clip();
  245. static void show_contour(), show_mapping(), show_format(), show_logscale();
  246. static void show_variables(), show_surface(), show_hidden3d(), show_label_contours();
  247. static void delete_label();
  248. static int assign_label_tag();
  249. static void delete_arrow();
  250. static int assign_arrow_tag();
  251. static TBOOLEAN set_one(), set_two(), set_three();
  252. static TBOOLEAN show_one(), show_two();
  253.  
  254. /******** The 'set' command ********/
  255. void
  256. set_command()
  257. {
  258. static char GPFAR setmess[] =
  259.     "valid set options:  'angles' '{no}arrow', {no}autoscale', \n\
  260.     '{no}border', 'boxwidth', '{no}clabel', '{no}clip', 'cntrparam', \n\
  261.         '{no}contour', 'data style', '{no}dgrid3d', 'dummy', 'format', \n\
  262.         'function style', '{no}grid', '{no}hidden3d', 'isosamples', '{no}key', \n\
  263.     '{no}label', '{no}logscale', 'mapping', 'offsets', 'output', \n\
  264.     '{no}parametric', '{no}polar', 'rrange', 'samples', 'size', \n\
  265.     '{no}surface', 'terminal', 'tics', 'ticslevel', '{no}time', 'title', \n\
  266.     'trange', 'urange', 'view', 'vrange', 'xlabel', 'xrange', '{no}xtics', \n\
  267.     'xmtics', 'xdtics', '{no}xzeroaxis', 'ylabel', 'yrange', '{no}ytics', \n\
  268.     'ymtics', 'ydtics', '{no}yzeroaxis', 'zero', '{no}zeroaxis', 'zlabel', \n\
  269.     'zrange', '{no}ztics', 'zmtics', 'zdtics'";
  270.  
  271.     c_token++;
  272.  
  273.     if (!set_one() && !set_two() && !set_three())
  274.     int_error(setmess, c_token);
  275. }
  276.  
  277. /* return TRUE if a command match, FALSE if not */
  278. static TBOOLEAN
  279. set_one()
  280. {
  281.     if (almost_equals(c_token,"ar$row")) {
  282.         c_token++;
  283.         set_arrow();
  284.     }
  285.     else if (almost_equals(c_token,"noar$row")) {
  286.         c_token++;
  287.         set_noarrow();
  288.     }
  289.      else if (almost_equals(c_token,"au$toscale")) {
  290.         c_token++;
  291.         if (END_OF_COMMAND) {
  292.            autoscale_r=autoscale_t = autoscale_x = autoscale_y = autoscale_z = TRUE;
  293.         } else if (equals(c_token, "xy") || equals(c_token, "yx")) {
  294.            autoscale_x = autoscale_y = TRUE;
  295.            c_token++;
  296.         } else if (equals(c_token, "r")) {
  297.            autoscale_r = TRUE;
  298.            c_token++;
  299.         } else if (equals(c_token, "t")) {
  300.            autoscale_t = TRUE;
  301.            c_token++;
  302.         } else if (equals(c_token, "x")) {
  303.            autoscale_x = TRUE;
  304.            c_token++;
  305.         } else if (equals(c_token, "y")) {
  306.            autoscale_y = TRUE;
  307.            c_token++;
  308.         } else if (equals(c_token, "z")) {
  309.            autoscale_z = TRUE;
  310.            c_token++;
  311.         }
  312.     } 
  313.     else if (almost_equals(c_token,"noau$toscale")) {
  314.         c_token++;
  315.         if (END_OF_COMMAND) {
  316.            autoscale_r=autoscale_t = autoscale_x = autoscale_y = autoscale_z = FALSE;
  317.         } else if (equals(c_token, "xy") || equals(c_token, "tyx")) {
  318.            autoscale_x = autoscale_y = FALSE;
  319.            c_token++;
  320.         } else if (equals(c_token, "r")) {
  321.            autoscale_r = FALSE;
  322.            c_token++;
  323.         } else if (equals(c_token, "t")) {
  324.            autoscale_t = FALSE;
  325.            c_token++;
  326.         } else if (equals(c_token, "x")) {
  327.            autoscale_x = FALSE;
  328.            c_token++;
  329.         } else if (equals(c_token, "y")) {
  330.            autoscale_y = FALSE;
  331.            c_token++;
  332.         } else if (equals(c_token, "z")) {
  333.            autoscale_z = FALSE;
  334.            c_token++;
  335.         }
  336.     } 
  337.     else if (almost_equals(c_token,"bor$der")) {
  338.         draw_border = TRUE;
  339.         c_token++;
  340.     }
  341.     else if (almost_equals(c_token,"nobor$der")) {
  342.         draw_border = FALSE;
  343.         c_token++;
  344.     }
  345.     else if (almost_equals(c_token,"box$width")) {
  346.         struct value a;
  347.         c_token++;
  348.         if (END_OF_COMMAND)
  349.             boxwidth = -1.0;
  350.         else
  351.             boxwidth = magnitude(const_express(&a));
  352.     }
  353.     else if (almost_equals(c_token,"c$lip")) {
  354.         c_token++;
  355.         if (END_OF_COMMAND)
  356.          /* assuming same as points */
  357.          clip_points = TRUE;
  358.         else if (almost_equals(c_token, "p$oints"))
  359.          clip_points = TRUE;
  360.         else if (almost_equals(c_token, "o$ne"))
  361.          clip_lines1 = TRUE;
  362.         else if (almost_equals(c_token, "t$wo"))
  363.          clip_lines2 = TRUE;
  364.         else
  365.          int_error("expecting 'points', 'one', or 'two'", c_token);
  366.         c_token++;
  367.     }
  368.     else if (almost_equals(c_token,"noc$lip")) {
  369.         c_token++;
  370.         if (END_OF_COMMAND) {
  371.            /* same as all three */
  372.            clip_points = FALSE;
  373.            clip_lines1 = FALSE;
  374.            clip_lines2 = FALSE;
  375.         } else if (almost_equals(c_token, "p$oints"))
  376.          clip_points = FALSE;
  377.         else if (almost_equals(c_token, "o$ne"))
  378.          clip_lines1 = FALSE;
  379.         else if (almost_equals(c_token, "t$wo"))
  380.          clip_lines2 = FALSE;
  381.         else
  382.          int_error("expecting 'points', 'one', or 'two'", c_token);
  383.         c_token++;
  384.     }
  385.     else if (almost_equals(c_token,"hi$dden3d")) {
  386. #ifdef LITE
  387.         printf(" Hidden Line Removal Not Supported in LITE version\n");
  388. #else
  389.         hidden3d = TRUE;
  390. #endif /* LITE */
  391.         c_token++;
  392.     }
  393.     else if (almost_equals(c_token,"nohi$dden3d")) {
  394. #ifdef LITE
  395.         printf(" Hidden Line Removal Not Supported in LITE version\n");
  396. #else
  397.         hidden3d = FALSE;
  398. #endif /* LITE */
  399.         c_token++;
  400.     }
  401.      else if (almost_equals(c_token,"cla$bel")) {
  402.          label_contours = TRUE;
  403.          c_token++;
  404.      }
  405.      else if (almost_equals(c_token,"nocla$bel")) {
  406.          label_contours = FALSE;
  407.          c_token++;
  408.       }
  409.     else if (almost_equals(c_token,"ma$pping3d")) {
  410.         c_token++;
  411.         if (END_OF_COMMAND)
  412.          /* assuming same as points */
  413.          mapping3d = MAP3D_CARTESIAN;
  414.         else if (almost_equals(c_token, "ca$rtesian"))
  415.          mapping3d = MAP3D_CARTESIAN;
  416.         else if (almost_equals(c_token, "s$pherical"))
  417.          mapping3d = MAP3D_SPHERICAL;
  418.         else if (almost_equals(c_token, "cy$lindrical"))
  419.          mapping3d = MAP3D_CYLINDRICAL;
  420.         else
  421.          int_error("expecting 'cartesian', 'spherical', or 'cylindrical'", c_token);
  422.         c_token++;
  423.     }
  424.     else if (almost_equals(c_token,"co$ntour")) {
  425.         c_token++;
  426.         if (END_OF_COMMAND)
  427.          /* assuming same as points */
  428.          draw_contour = CONTOUR_BASE;
  429.         else if (almost_equals(c_token, "ba$se"))
  430.          draw_contour = CONTOUR_BASE;
  431.         else if (almost_equals(c_token, "s$urface"))
  432.          draw_contour = CONTOUR_SRF;
  433.         else if (almost_equals(c_token, "bo$th"))
  434.          draw_contour = CONTOUR_BOTH;
  435.         else
  436.          int_error("expecting 'base', 'surface', or 'both'", c_token);
  437.         c_token++;
  438.     }
  439.     else if (almost_equals(c_token,"noco$ntour")) {
  440.         c_token++;
  441.         draw_contour = CONTOUR_NONE;
  442.     }
  443.     else if (almost_equals(c_token,"cntrp$aram")) {
  444.         struct value a;
  445.  
  446.         c_token++;
  447.         if (END_OF_COMMAND) {
  448.          /* assuming same as defaults */
  449.          contour_pts = 5;
  450.          contour_kind = CONTOUR_KIND_LINEAR;
  451.          contour_order = 4;
  452.          contour_levels = 5;
  453.           levels_kind = LEVELS_AUTO;
  454.         }
  455.         else if (almost_equals(c_token, "p$oints")) {
  456.          c_token++;
  457.          contour_pts = (int) real(const_express(&a));
  458.         }
  459.         else if (almost_equals(c_token, "li$near")) {
  460.          c_token++;
  461.          contour_kind = CONTOUR_KIND_LINEAR;
  462.         }
  463.         else if (almost_equals(c_token, "c$ubicspline")) {
  464.          c_token++;
  465.          contour_kind = CONTOUR_KIND_CUBIC_SPL;
  466.         }
  467.         else if (almost_equals(c_token, "b$spline")) {
  468.          c_token++;
  469.          contour_kind = CONTOUR_KIND_BSPLINE;
  470.         }
  471.  
  472.            else if (almost_equals(c_token, "le$vels")) {
  473.                int i=0;  /* local counter */
  474.                c_token++;
  475.             /*  RKC: I have modified the next two:
  476.              *   to use commas to separate list elements as in xtics
  477.               *   so that incremental lists start,incr[,end]as in "
  478.               */
  479.                if (almost_equals(c_token, "di$screte")) {
  480.                   levels_kind = LEVELS_DISCRETE;
  481.                   c_token++;
  482.                 if(END_OF_COMMAND)
  483.                  int_error("expecting discrete level", c_token);
  484.                 else
  485.                   levels_list[i++] = real(const_express(&a));
  486.                 while(!END_OF_COMMAND){
  487.                   if (!equals(c_token, ","))
  488.                     int_error("expecting comma to separate discrete levels", c_token);
  489.                   c_token++;
  490.                   levels_list[i++] =  real(const_express(&a));
  491.                 }
  492.                   contour_levels = i;
  493.                }
  494.                else if (almost_equals(c_token, "in$cremental")) {
  495.                   levels_kind = LEVELS_INCREMENTAL;
  496.                   c_token++;
  497.                 levels_list[i++] =  real(const_express(&a));
  498.                 if (!equals(c_token, ","))
  499.                   int_error("expecting comma to separate start,incr levels", c_token);
  500.                 c_token++;
  501.                 if((levels_list[i++] = real(const_express(&a)))==0)
  502.                   int_error("increment cannot be 0", c_token);
  503.                  if(!END_OF_COMMAND){
  504.                   if (!equals(c_token, ","))
  505.                     int_error("expecting comma to separate incr,stop levels", c_token);
  506.                   c_token++;
  507.                  contour_levels = (real(const_express(&a))-levels_list[0])/levels_list[1];
  508.                   }
  509.                }
  510.                else if (almost_equals(c_token, "au$to")) {
  511.                    levels_kind = LEVELS_AUTO;
  512.                  c_token++;
  513.                  if(!END_OF_COMMAND)
  514.                      contour_levels = (int) real(const_express(&a));
  515.              }
  516.              else {
  517.               if(levels_kind == LEVELS_DISCRETE)
  518.                 int_error("Levels type is discrete, ignoring new number of contour levels", c_token);
  519.                 contour_levels = (int) real(const_express(&a));
  520.             }
  521.          }
  522.         else if (almost_equals(c_token, "o$rder")) {
  523.          int order;
  524.          c_token++;
  525.          order = (int) real(const_express(&a));
  526.          if ( order < 2 || order > 10 )
  527.              int_error("bspline order must be in [2..10] range.", c_token);
  528.          contour_order = order;
  529.         }
  530.         else
  531.          int_error("expecting 'linear', 'cubicspline', 'bspline', 'points', 'levels' or 'order'", c_token);
  532.         c_token++;
  533.     }
  534.     else if (almost_equals(c_token,"da$ta")) {
  535.         c_token++;
  536.         if (!almost_equals(c_token,"s$tyle"))
  537.             int_error("expecting keyword 'style'",c_token);
  538.         data_style = get_style();
  539.     }
  540.     else if (almost_equals(c_token,"dg$rid3d")) {
  541.         int i;
  542.         TBOOLEAN was_comma = TRUE;
  543.         int local_vals[3];
  544.         struct value a;
  545.  
  546.         local_vals[0] = dgrid3d_row_fineness;
  547.         local_vals[1] = dgrid3d_col_fineness;
  548.         local_vals[2] = dgrid3d_norm_value;
  549.         c_token++;
  550.         for (i = 0; i < 3 && !(END_OF_COMMAND);) {
  551.             if (equals(c_token,",")) {
  552.                 if (was_comma) i++;
  553.                 was_comma = TRUE;
  554.                 c_token++;
  555.             }
  556.             else {
  557.                 if (!was_comma)
  558.                     int_error("',' expected",c_token);
  559.                 local_vals[i] = real(const_express(&a));
  560.                 i++;
  561.                 was_comma = FALSE;
  562.             }
  563.         }
  564.  
  565.  
  566.         if (local_vals[0] < 2 || local_vals[0] > 1000)
  567.             int_error("Row size must be in [2:1000] range; size unchanged",
  568.                   c_token);
  569.         if (local_vals[1] < 2 || local_vals[1] > 1000)
  570.             int_error("Col size must be in [2:1000] range; size unchanged",
  571.                   c_token);
  572.         if (local_vals[2] < 1 || local_vals[2] > 100)
  573.             int_error("Norm must be in [1:100] range; norm unchanged", c_token);
  574.  
  575.         dgrid3d_row_fineness = local_vals[0];
  576.         dgrid3d_col_fineness = local_vals[1];
  577.         dgrid3d_norm_value = local_vals[2];
  578.         dgrid3d = TRUE;
  579.     }
  580.     else if (almost_equals(c_token,"nodg$rid3d")) {
  581.         c_token++;
  582.         dgrid3d = FALSE;
  583.     }
  584.     else if (almost_equals(c_token,"du$mmy")) {
  585.         c_token++;
  586.         if (END_OF_COMMAND)
  587.             int_error("expecting dummy variable name", c_token);
  588.         else {
  589.             if (!equals(c_token,","))
  590.                 copy_str(dummy_var[0],c_token++);
  591.             if (!END_OF_COMMAND && equals(c_token,",")) {
  592.                 c_token++;
  593.                 if (END_OF_COMMAND)
  594.                     int_error("expecting second dummy variable name", c_token);
  595.                 copy_str(dummy_var[1],c_token++);
  596.                 }
  597.         }
  598.     }
  599.     else if (almost_equals(c_token,"fo$rmat")) {
  600.         TBOOLEAN setx, sety, setz;
  601.         c_token++;
  602.         if (equals(c_token,"x")) {
  603.             setx = TRUE; sety = setz = FALSE;
  604.             c_token++;
  605.         }
  606.         else if (equals(c_token,"y")) {
  607.             setx = setz = FALSE; sety = TRUE;
  608.             c_token++;
  609.         }
  610.         else if (equals(c_token,"z")) {
  611.             setx = sety = FALSE; setz = TRUE;
  612.             c_token++;
  613.         }
  614.         else if (equals(c_token,"xy") || equals(c_token,"yx")) {
  615.             setx = sety = TRUE; setz = FALSE;
  616.             c_token++;
  617.         }
  618.         else if (isstring(c_token) || END_OF_COMMAND) {
  619.             /* Assume he wants all */
  620.             setx = sety = setz = TRUE;
  621.         }
  622.         if (END_OF_COMMAND) {
  623.             if (setx)
  624.                 (void) strcpy(xformat,DEF_FORMAT);
  625.             if (sety)
  626.                 (void) strcpy(yformat,DEF_FORMAT);
  627.             if (setz)
  628.                 (void) strcpy(zformat,DEF_FORMAT);
  629.         }
  630.         else {
  631.             if (!isstring(c_token))
  632.               int_error("expecting format string",c_token);
  633.             else {
  634.                 if (setx)
  635.                  quote_str(xformat,c_token);
  636.                 if (sety)
  637.                  quote_str(yformat,c_token);
  638.                 if (setz)
  639.                  quote_str(zformat,c_token);
  640.                 c_token++;
  641.             }
  642.         }
  643.     }
  644.     else if (almost_equals(c_token,"fu$nction")) {
  645.         c_token++;
  646.         if (!almost_equals(c_token,"s$tyle"))
  647.             int_error("expecting keyword 'style'",c_token);
  648.         func_style = get_style();
  649.     }
  650.     else if (almost_equals(c_token,"la$bel")) {
  651.         c_token++;
  652.         set_label();
  653.     }
  654.     else if (almost_equals(c_token,"nola$bel")) {
  655.         c_token++;
  656.         set_nolabel();
  657.     }
  658.     else if (almost_equals(c_token,"lo$gscale")) {
  659.         c_token++;
  660.         if (END_OF_COMMAND) {
  661.         is_log_x = is_log_y = is_log_z = TRUE;
  662.         base_log_x = base_log_y = base_log_z = 10.0;
  663.         log_base_log_x = log_base_log_y = log_base_log_z = log(10.0);
  664.         } else {
  665.         TBOOLEAN change_x = FALSE;
  666.         TBOOLEAN change_y = FALSE;
  667.         TBOOLEAN change_z = FALSE;
  668.         if (chr_in_str(c_token, 'x'))
  669.             change_x = TRUE;
  670.         if (chr_in_str(c_token, 'y'))
  671.             change_y = TRUE;
  672.         if (chr_in_str(c_token, 'z'))
  673.             change_z = TRUE;
  674.         c_token++;
  675.                 if (END_OF_COMMAND) {
  676.             if (change_x) {
  677.             is_log_x = TRUE;
  678.             base_log_x = 10.0;
  679.             log_base_log_x = log(10.0);
  680.             }
  681.             if (change_y) {
  682.             is_log_y = TRUE;
  683.             base_log_y = 10.0;
  684.             log_base_log_y = log(10.0);
  685.             }
  686.             if (change_z) {
  687.             is_log_z = TRUE;
  688.             base_log_z = 10.0;
  689.             log_base_log_z = log(10.0);
  690.             }
  691.         } else {
  692.             struct value a;
  693.             double newbase = magnitude(const_express(&a));
  694.             c_token++;
  695.             if (newbase < 1.1)
  696.             int_error("log base must be >= 1.1; logscale unchanged",
  697.                 c_token);
  698.             else {
  699.             if (change_x) {
  700.                 is_log_x = TRUE;
  701.                 base_log_x = newbase;
  702.                 log_base_log_x = log(newbase);
  703.             }
  704.             if (change_y) {
  705.                 is_log_y = TRUE;
  706.                 base_log_y = newbase;
  707.                 log_base_log_y = log(newbase);
  708.             }
  709.             if (change_z) {
  710.                 is_log_z = TRUE;
  711.                 base_log_z = newbase;
  712.                 log_base_log_z = log(newbase);
  713.             }
  714.             }
  715.         }
  716.         }
  717.     }
  718.     else if (almost_equals(c_token,"nolo$gscale")) {
  719.         c_token++;
  720.         if (END_OF_COMMAND) {
  721.         is_log_x = is_log_y = is_log_z = FALSE;
  722.         } else {
  723.         if (chr_in_str(c_token, 'x')) {
  724.             is_log_x = FALSE;
  725.             base_log_x = 0.0;
  726.             log_base_log_x = 0.0;
  727.                 }
  728.         if (chr_in_str(c_token, 'y')) {
  729.             is_log_y = FALSE;
  730.             base_log_y = 0.0;
  731.             log_base_log_y = 0.0;
  732.                 }
  733.         if (chr_in_str(c_token, 'z')) {
  734.             is_log_z = FALSE;
  735.             base_log_z = 0.0;
  736.             log_base_log_z = 0.0;
  737.                 }
  738.         c_token++;
  739.         }
  740.     } 
  741.     else if (almost_equals(c_token,"of$fsets")) {
  742.         c_token++;
  743.         if (END_OF_COMMAND) {
  744.             loff = roff = toff = boff = 0.0;  /* Reset offsets */
  745.         }
  746.         else {
  747.             load_offsets (&loff,&roff,&toff,&boff);
  748.         }
  749.     }
  750.     else
  751.         return(FALSE);    /* no command match */
  752.     return(TRUE);
  753. }
  754.  
  755.  
  756. /* return TRUE if a command match, FALSE if not */
  757. static TBOOLEAN
  758. set_two()
  759. {
  760.      char testfile[MAX_LINE_LEN+1];
  761. #if defined(unix) || defined(PIPES)
  762.      static TBOOLEAN pipe_open = FALSE;
  763. #endif /* unix || PIPES */
  764.  
  765.     if (almost_equals(c_token,"o$utput")) {
  766.         register FILE *f;
  767.  
  768.         c_token++;
  769.         if (term && term_init)
  770.             (*term_tbl[term].reset)();
  771.         if (END_OF_COMMAND) {    /* no file specified */
  772.              UP_redirect (4);
  773.             if (outfile != stdout) { /* Never close stdout */
  774. #if defined(unix) || defined(PIPES)
  775.                 if ( pipe_open ) {
  776.                     (void) pclose(outfile);
  777.                     pipe_open = FALSE;
  778.                 } else
  779. #endif /* unix || PIPES */
  780. #ifdef _Windows
  781.                   if ( !stricmp(outstr,"'PRN'") )
  782.                     close_printer();
  783.                   else
  784. #endif
  785.                     (void) fclose(outfile);
  786.             }
  787.             outfile = stdout; /* Don't dup... */
  788.             term_init = FALSE;
  789.             (void) strcpy(outstr,"STDOUT");
  790.         } else if (!isstring(c_token))
  791.             int_error("expecting filename",c_token);
  792.         else {
  793.             quote_str(testfile,c_token);
  794. #if defined(unix) || defined(PIPES)
  795.             if ( *testfile == '|' ) {
  796.               if ((f = popen(testfile+1,"w")) == (FILE *)NULL)
  797.                 os_error("cannot create pipe; output not changed",c_token);
  798.               else
  799.                 pipe_open = TRUE;
  800.             } else
  801. #endif /* unix || PIPES */
  802. #ifdef _Windows
  803.             if ( !stricmp(outstr,"'PRN'") ) {
  804.                 /* we can't call open_printer() while printer is open, so */
  805.                 close_printer();    /* close printer immediately if open */
  806.                 outfile = stdout;    /* and reset output to stdout */
  807.                 term_init = FALSE;
  808.                 (void) strcpy(outstr,"STDOUT");
  809.             }
  810.             if ( !stricmp(testfile,"PRN") ) {
  811.               if ((f = open_printer()) == (FILE *)NULL)
  812.                 os_error("cannot open printer temporary file; output may have changed",c_token);
  813.             } else
  814. #endif
  815.               if ((f = fopen(testfile,"w")) == (FILE *)NULL)
  816.                 os_error("cannot open file; output not changed",c_token);
  817.             if (outfile != stdout) /* Never close stdout */
  818. #if defined(unix) || defined(PIPES)
  819.                 if( pipe_open ) {
  820.                 (void) pclose(outfile);
  821.                 pipe_open=FALSE;
  822.                 } else
  823. #endif /* unix || PIPES */
  824.                 (void) fclose(outfile);
  825.             outfile = f;
  826.             term_init = FALSE;
  827.             outstr[0] = '\'';
  828.             (void) strcat(strcpy(outstr+1,testfile),"'");
  829.              UP_redirect (1);
  830.         }
  831.         c_token++;
  832.     }
  833.     else if (almost_equals(c_token,"tit$le")) {
  834.         set_xyzlabel(title,&title_xoffset,&title_yoffset);
  835.     }
  836.     else if (almost_equals(c_token,"xl$abel")) {
  837.         set_xyzlabel(xlabel,&xlabel_xoffset,&xlabel_yoffset);
  838.     }
  839.     else if (almost_equals(c_token,"yl$abel")) {
  840.         set_xyzlabel(ylabel,&ylabel_xoffset,&ylabel_yoffset);
  841.     }
  842.     else if (almost_equals(c_token,"zl$abel")) {
  843.         set_xyzlabel(zlabel,&zlabel_xoffset,&zlabel_yoffset);
  844.     }
  845.     else if (almost_equals(c_token,"xzero$axis")) {
  846.         c_token++;
  847.         xzeroaxis = TRUE;
  848.     } 
  849.     else if (almost_equals(c_token,"yzero$axis")) {
  850.         c_token++;
  851.         yzeroaxis = TRUE;
  852.     } 
  853.     else if (almost_equals(c_token,"zeroa$xis")) {
  854.         c_token++;
  855.         yzeroaxis = TRUE;
  856.         xzeroaxis = TRUE;
  857.     } 
  858.     else if (almost_equals(c_token,"noxzero$axis")) {
  859.         c_token++;
  860.         xzeroaxis = FALSE;
  861.     } 
  862.     else if (almost_equals(c_token,"noyzero$axis")) {
  863.         c_token++;
  864.         yzeroaxis = FALSE;
  865.     } 
  866.     else if (almost_equals(c_token,"nozero$axis")) {
  867.         c_token++;
  868.         xzeroaxis = FALSE;
  869.         yzeroaxis = FALSE;
  870.     } 
  871.     else if (almost_equals(c_token,"par$ametric")) {
  872.         if (!parametric) {
  873.            parametric = TRUE;
  874.            strcpy (dummy_var[0], "t");
  875.            strcpy (dummy_var[1], "y");
  876.            if (interactive)
  877.              (void) fprintf(stderr,"\n\tdummy variable is t for curves, u/v for surfaces\n");
  878.         }
  879.         c_token++;
  880.     }
  881.     else if (almost_equals(c_token,"nopar$ametric")) {
  882.         if (parametric) {
  883.            parametric = FALSE;
  884.            strcpy (dummy_var[0], "x");
  885.            strcpy (dummy_var[1], "y");
  886.            if (interactive)
  887.              (void) fprintf(stderr,"\n\tdummy variable is x for curves, x/y for surfaces\n");
  888.         }
  889.         c_token++;
  890.     }
  891.     else if (almost_equals(c_token,"pol$ar")) {
  892.         if (!polar) {
  893.             polar = TRUE;
  894.             if (parametric) {
  895.                 tmin = 0.0;
  896.                 tmax = 2*Pi;
  897.             } else if (angles_format == ANGLES_DEGREES) {
  898.                 xmin = 0.0;
  899.                 xmax = 360.0;
  900.             } else {
  901.                 xmin = 0.0;
  902.                 xmax = 2*Pi;
  903.             }
  904.         }
  905.         c_token++;
  906.     }
  907.     else if (almost_equals(c_token,"nopo$lar")) {
  908.         if (polar) {
  909.             polar = FALSE;
  910.             if (parametric) {
  911.                 tmin = -5.0;
  912.                 tmax = 5.0;
  913.             } else {
  914.                 xmin = -10.0;
  915.                 xmax = 10.0;
  916.             }
  917.         }
  918.         c_token++;
  919.     }
  920.     else if (almost_equals(c_token,"an$gles")) {
  921.         c_token++;
  922.         if (END_OF_COMMAND) {
  923.         /* assuming same as defaults */
  924.         angles_format = ANGLES_RADIANS;
  925.         }
  926.         else if (almost_equals(c_token, "r$adians")) {
  927.         angles_format = ANGLES_RADIANS;
  928.         c_token++;
  929.         }
  930.         else if (almost_equals(c_token, "d$egrees")) {
  931.         angles_format = ANGLES_DEGREES;
  932.         c_token++;
  933.         }
  934.         else
  935.          int_error("expecting 'radians' or 'degrees'", c_token);
  936.     }
  937.     else if (almost_equals(c_token,"g$rid")) {
  938.         grid = TRUE;
  939.         c_token++;
  940.     }
  941.     else if (almost_equals(c_token,"nog$rid")) {
  942.         grid = FALSE;
  943.         c_token++;
  944.     }
  945.     else if (almost_equals(c_token,"su$rface")) {
  946.         draw_surface = TRUE;
  947.         c_token++;
  948.     }
  949.     else if (almost_equals(c_token,"nosu$rface")) {
  950.         draw_surface = FALSE;
  951.         c_token++;
  952.     }
  953.     else if (almost_equals(c_token,"k$ey")) {
  954.         struct value a;
  955.         c_token++;
  956.         if (END_OF_COMMAND) {
  957.             key = -1;
  958.         } 
  959.         else {
  960.             key_x = real(const_express(&a));
  961.             if (!equals(c_token,","))
  962.                 int_error("',' expected",c_token);
  963.             c_token++;
  964.             key_y = real(const_express(&a));
  965.             if (equals(c_token,","))
  966.             {
  967.                     c_token++;
  968.                 key_z = real(const_express(&a));
  969.             }
  970.             key = 1;
  971.         } 
  972.     }
  973.     else if (almost_equals(c_token,"nok$ey")) {
  974.         key = 0;
  975.         c_token++;
  976.     }
  977.     else if (almost_equals(c_token,"tic$s")) {
  978.         tic_in = TRUE;
  979.         c_token++;
  980.         if (almost_equals(c_token,"i$n")) {
  981.             tic_in = TRUE;
  982.             c_token++;
  983.         }
  984.         else if (almost_equals(c_token,"o$ut")) {
  985.             tic_in = FALSE;
  986.             c_token++;
  987.         }
  988.     }
  989.      else if (almost_equals(c_token,"xmt$ics")) {
  990.      xtics = TRUE;
  991.      c_token++;
  992.      if(xticdef.type == TIC_USER){
  993.          free_marklist(xticdef.def.user);
  994.          xticdef.def.user = NULL;
  995.      }
  996.     xticdef.type = TIC_MONTH;
  997.      }
  998.      else if (almost_equals(c_token,"xdt$ics")) {
  999.      xtics = TRUE;
  1000.      c_token++;
  1001.      if(xticdef.type == TIC_USER){
  1002.          free_marklist(xticdef.def.user);
  1003.          xticdef.def.user = NULL;
  1004.      }
  1005.     xticdef.type = TIC_DAY;
  1006.      }
  1007.      else if (almost_equals(c_token,"xt$ics")) {
  1008.         xtics = TRUE;
  1009.         c_token++;
  1010.         if (END_OF_COMMAND) { /* reset to default */
  1011.            if (xticdef.type == TIC_USER) {
  1012.               free_marklist(xticdef.def.user);
  1013.               xticdef.def.user = NULL;
  1014.            }
  1015.            xticdef.type = TIC_COMPUTED;
  1016.         }
  1017.         else
  1018.          load_tics(&xticdef);
  1019.     } 
  1020.      else if (almost_equals(c_token,"noxt$ics")) {
  1021.         xtics = FALSE;
  1022.         c_token++;
  1023.     } 
  1024.      else if (almost_equals(c_token,"ymt$ics")) {
  1025.      ytics = TRUE;
  1026.      c_token++;
  1027.      if(yticdef.type == TIC_USER){
  1028.          free_marklist(yticdef.def.user);
  1029.          yticdef.def.user = NULL;
  1030.      }
  1031.     yticdef.type = TIC_MONTH;
  1032.      }
  1033.      else if (almost_equals(c_token,"ydt$ics")) {
  1034.      ytics = TRUE;
  1035.      c_token++;
  1036.      if(yticdef.type == TIC_USER){
  1037.          free_marklist(yticdef.def.user);
  1038.          yticdef.def.user = NULL;
  1039.      }
  1040.     yticdef.type = TIC_DAY;
  1041.      }
  1042.      else if (almost_equals(c_token,"yt$ics")) {
  1043.         ytics = TRUE;
  1044.         c_token++;
  1045.         if (END_OF_COMMAND) { /* reset to default */
  1046.            if (yticdef.type == TIC_USER) {
  1047.               free_marklist(yticdef.def.user);
  1048.               yticdef.def.user = NULL;
  1049.            }
  1050.            yticdef.type = TIC_COMPUTED;
  1051.         }
  1052.         else
  1053.          load_tics(&yticdef);
  1054.     } 
  1055.      else if (almost_equals(c_token,"noyt$ics")) {
  1056.         ytics = FALSE;
  1057.         c_token++;
  1058.     } 
  1059.      else if (almost_equals(c_token,"zmt$ics")) {
  1060.      ztics = TRUE;
  1061.      c_token++;
  1062.      if(zticdef.type == TIC_USER){
  1063.          free_marklist(zticdef.def.user);
  1064.          zticdef.def.user = NULL;
  1065.      }
  1066.     zticdef.type = TIC_MONTH;
  1067.      }
  1068.      else if (almost_equals(c_token,"zdt$ics")) {
  1069.      ztics = TRUE;
  1070.      c_token++;
  1071.      if(zticdef.type == TIC_USER){
  1072.          free_marklist(zticdef.def.user);
  1073.          zticdef.def.user = NULL;
  1074.      }
  1075.     zticdef.type = TIC_DAY;
  1076.      }
  1077.      else if (almost_equals(c_token,"zt$ics")) {
  1078.         ztics = TRUE;
  1079.         c_token++;
  1080.         if (END_OF_COMMAND) { /* reset to default */
  1081.            if (zticdef.type == TIC_USER) {
  1082.               free_marklist(zticdef.def.user);
  1083.               zticdef.def.user = NULL;
  1084.            }
  1085.            zticdef.type = TIC_COMPUTED;
  1086.         }
  1087.         else
  1088.          load_tics(&zticdef);
  1089.     } 
  1090.      else if (almost_equals(c_token,"nozt$ics")) {
  1091.         ztics = FALSE;
  1092.         c_token++;
  1093.     } 
  1094.     else if (almost_equals(c_token,"ticsl$evel")) {
  1095.         double tlvl;
  1096.         struct value a;
  1097.  
  1098.         c_token++;
  1099.         tlvl = real(const_express(&a));
  1100.         if (tlvl < 0.0)
  1101.             int_error("tics level must be > 0; ticslevel unchanged",
  1102.                 c_token);
  1103.         else {
  1104.             ticslevel = tlvl;
  1105.         }
  1106.     }
  1107.     else
  1108.     return(FALSE);    /* no command match */
  1109.  
  1110.     return(TRUE);
  1111. }
  1112.  
  1113.  
  1114.  
  1115. /* return TRUE if a command match, FALSE if not */
  1116. static TBOOLEAN
  1117. set_three()
  1118. {
  1119.      if (almost_equals(c_token,"sa$mples")) {
  1120.         register int tsamp1, tsamp2;
  1121.         struct value a;
  1122.  
  1123.         c_token++;
  1124.         tsamp1 = (int)magnitude(const_express(&a));
  1125.         tsamp2 = tsamp1;
  1126.         if (!END_OF_COMMAND) {
  1127.             if (!equals(c_token,","))
  1128.                 int_error("',' expected",c_token);
  1129.             c_token++;
  1130.             tsamp2 = (int)magnitude(const_express(&a));
  1131.         }
  1132.         if (tsamp1 < 2 || tsamp2 < 2)
  1133.             int_error("sampling rate must be > 1; sampling unchanged",
  1134.                 c_token);
  1135.         else {
  1136.                 extern struct surface_points *first_3dplot;
  1137.             register struct surface_points *f_3dp = first_3dplot;
  1138.  
  1139.             first_3dplot = NULL;
  1140.             sp_free(f_3dp);
  1141.  
  1142.             samples = tsamp1;
  1143.             samples_1 = tsamp1;
  1144.             samples_2 = tsamp2;
  1145.         }
  1146.     }
  1147.     else if (almost_equals(c_token,"isosa$mples")) {
  1148.         register int tsamp1, tsamp2;
  1149.         struct value a;
  1150.  
  1151.         c_token++;
  1152.         tsamp1 = (int)magnitude(const_express(&a));
  1153.         tsamp2 = tsamp1;
  1154.         if (!END_OF_COMMAND) {
  1155.             if (!equals(c_token,","))
  1156.                 int_error("',' expected",c_token);
  1157.             c_token++;
  1158.             tsamp2 = (int)magnitude(const_express(&a));
  1159.         }
  1160.         if (tsamp1 < 2 || tsamp2 < 2)
  1161.             int_error("sampling rate must be > 1; sampling unchanged",
  1162.                 c_token);
  1163.         else {
  1164.                 extern struct curve_points *first_plot;
  1165.                 extern struct surface_points *first_3dplot;
  1166.             register struct curve_points *f_p = first_plot;
  1167.             register struct surface_points *f_3dp = first_3dplot;
  1168.  
  1169.             first_plot = NULL;
  1170.             first_3dplot = NULL;
  1171.             cp_free(f_p);
  1172.             sp_free(f_3dp);
  1173.  
  1174.             iso_samples_1 = tsamp1;
  1175.             iso_samples_2 = tsamp2;
  1176.         }
  1177.     }
  1178.     else if (almost_equals(c_token,"si$ze")) {
  1179.         struct value s;
  1180.         c_token++;
  1181.         if (END_OF_COMMAND) {
  1182.             xsize = 1.0;
  1183.             ysize = 1.0;
  1184.         } 
  1185.         else {
  1186.                 xsize=real(const_express(&s));
  1187.                 if (!equals(c_token,","))
  1188.                     int_error("',' expected",c_token);
  1189.                 c_token++;
  1190.                 ysize=real(const_express(&s));
  1191.         } 
  1192.     } 
  1193.     else if (almost_equals(c_token,"t$erminal")) {
  1194.         c_token++;
  1195.         if (END_OF_COMMAND) {
  1196.             list_terms();
  1197.             screen_ok = FALSE;
  1198.         }
  1199.         else {
  1200.             if (term && term_init) {
  1201.                 (*term_tbl[term].reset)();
  1202.                 (void) fflush(outfile);
  1203.             }
  1204.             term = set_term(c_token);
  1205.             c_token++;
  1206.  
  1207.             /* get optional mode parameters */
  1208.             if (term)
  1209.                 (*term_tbl[term].options)();
  1210.             if (interactive && *term_options)
  1211.                 fprintf(stderr,"Options are '%s'\n",term_options);
  1212.         }
  1213.     }
  1214.     else if (almost_equals(c_token,"tim$e")) {
  1215.         timedate = TRUE;
  1216.         c_token++;
  1217.         if (!END_OF_COMMAND) {
  1218.             struct value a;
  1219.  
  1220.             /* We have x,y offsets specified */
  1221.             if (!equals(c_token,","))
  1222.                 time_xoffset = (int)real(const_express(&a));
  1223.             if (!END_OF_COMMAND && equals(c_token,",")) {
  1224.                 c_token++;
  1225.                 time_yoffset = (int)real(const_express(&a));
  1226.             }
  1227.         }
  1228.     }
  1229.     else if (almost_equals(c_token,"not$ime")) {
  1230.         timedate = FALSE;
  1231.         c_token++;
  1232.     }
  1233.     else if (almost_equals(c_token,"rr$ange")) {
  1234.          TBOOLEAN changed;
  1235.         c_token++;
  1236.         if (!equals(c_token,"["))
  1237.             int_error("expecting '['",c_token);
  1238.         c_token++;
  1239.         changed = load_range(&rmin,&rmax);
  1240.         if (!equals(c_token,"]"))
  1241.           int_error("expecting ']'",c_token);
  1242.         c_token++;
  1243.         if (changed)
  1244.           autoscale_r = FALSE;
  1245.     }
  1246.     else if (almost_equals(c_token,"tr$ange")) {
  1247.          TBOOLEAN changed;
  1248.         c_token++;
  1249.         if (!equals(c_token,"["))
  1250.             int_error("expecting '['",c_token);
  1251.         c_token++;
  1252.         changed = load_range(&tmin,&tmax);
  1253.         if (!equals(c_token,"]"))
  1254.           int_error("expecting ']'",c_token);
  1255.         c_token++;
  1256.         if (changed)
  1257.           autoscale_t = FALSE;
  1258.     }
  1259.     else if (almost_equals(c_token,"ur$ange")) {
  1260.          TBOOLEAN changed;
  1261.         c_token++;
  1262.         if (!equals(c_token,"["))
  1263.             int_error("expecting '['",c_token);
  1264.         c_token++;
  1265.         changed = load_range(&umin,&umax);
  1266.         if (!equals(c_token,"]"))
  1267.           int_error("expecting ']'",c_token);
  1268.         c_token++;
  1269.         if (changed)
  1270.           autoscale_u = FALSE;
  1271.     }
  1272.     else if (almost_equals(c_token,"vi$ew")) {
  1273.         int i;
  1274.         TBOOLEAN was_comma = TRUE;
  1275.         double local_vals[4];
  1276.         struct value a;
  1277.  
  1278.         local_vals[0] = surface_rot_x;
  1279.         local_vals[1] = surface_rot_z;
  1280.         local_vals[2] = surface_scale;
  1281.         local_vals[3] = surface_zscale;
  1282.         c_token++;
  1283.         for (i = 0; i < 4 && !(END_OF_COMMAND);) {
  1284.             if (equals(c_token,",")) {
  1285.                 if (was_comma) i++;
  1286.                 was_comma = TRUE;
  1287.                 c_token++;
  1288.             }
  1289.             else {
  1290.                 if (!was_comma)
  1291.                     int_error("',' expected",c_token);
  1292.                 local_vals[i] = real(const_express(&a));
  1293.                 i++;
  1294.                 was_comma = FALSE;
  1295.             }
  1296.         }
  1297.  
  1298.         if (local_vals[0] < 0 || local_vals[0] > 180)
  1299.             int_error("rot_x must be in [0:180] degrees range; view unchanged",
  1300.                   c_token);
  1301.         if (local_vals[1] < 0 || local_vals[1] > 360)
  1302.             int_error("rot_z must be in [0:360] degrees range; view unchanged",
  1303.                   c_token);
  1304.         if (local_vals[2] < 1e-6)
  1305.             int_error("scale must be > 0; view unchanged", c_token);
  1306.         if (local_vals[3] < 1e-6)
  1307.             int_error("zscale must be > 0; view unchanged", c_token);
  1308.  
  1309.         surface_rot_x = local_vals[0];
  1310.         surface_rot_z = local_vals[1];
  1311.         surface_scale = local_vals[2];
  1312.         surface_zscale = local_vals[3];
  1313.     }
  1314.     else if (almost_equals(c_token,"vr$ange")) {
  1315.          TBOOLEAN changed;
  1316.         c_token++;
  1317.         if (!equals(c_token,"["))
  1318.             int_error("expecting '['",c_token);
  1319.         c_token++;
  1320.         changed = load_range(&vmin,&vmax);
  1321.         if (!equals(c_token,"]"))
  1322.           int_error("expecting ']'",c_token);
  1323.         c_token++;
  1324.         if (changed)
  1325.           autoscale_v = FALSE;
  1326.     }
  1327.     else if (almost_equals(c_token,"xr$ange")) {
  1328.          TBOOLEAN changed;
  1329.         c_token++;
  1330.         if (!equals(c_token,"["))
  1331.             int_error("expecting '['",c_token);
  1332.         c_token++;
  1333.         changed = load_range(&xmin,&xmax);
  1334.         if (!equals(c_token,"]"))
  1335.           int_error("expecting ']'",c_token);
  1336.         c_token++;
  1337.         if (changed)
  1338.           autoscale_x = FALSE;
  1339.     }
  1340.     else if (almost_equals(c_token,"yr$ange")) {
  1341.          TBOOLEAN changed;
  1342.         c_token++;
  1343.         if (!equals(c_token,"["))
  1344.             int_error("expecting '['",c_token);
  1345.         c_token++;
  1346.         changed = load_range(&ymin,&ymax);
  1347.         if (!equals(c_token,"]"))
  1348.           int_error("expecting ']'",c_token);
  1349.         c_token++;
  1350.         if (changed)
  1351.           autoscale_y = FALSE;
  1352.     }
  1353.     else if (almost_equals(c_token,"zr$ange")) {
  1354.          TBOOLEAN changed;
  1355.         c_token++;
  1356.         if (!equals(c_token,"["))
  1357.             int_error("expecting '['",c_token);
  1358.         c_token++;
  1359.         changed = load_range(&zmin,&zmax);
  1360.         if (!equals(c_token,"]"))
  1361.           int_error("expecting ']'",c_token);
  1362.         c_token++;
  1363.         if (changed)
  1364.           autoscale_z = FALSE;
  1365.     }
  1366.     else if (almost_equals(c_token,"z$ero")) {
  1367.         struct value a;
  1368.         c_token++;
  1369.         zero = magnitude(const_express(&a));
  1370.     }
  1371.     else
  1372.         return(FALSE);    /* no command match */
  1373.     return(TRUE);
  1374. }
  1375.  
  1376. /*********** Support functions for set_command ***********/
  1377.  
  1378. /* process a 'set {x/y/z}label command */
  1379. /* set {x/y/z}label {label_text} {x}{,y} */
  1380. static void set_xyzlabel(str,xpos,ypos)
  1381. char *str;
  1382. int *xpos,*ypos;
  1383. {
  1384.     c_token++;
  1385.     if (END_OF_COMMAND) {    /* no label specified */
  1386.         str[0] = '\0';
  1387.     } else {
  1388.         if (isstring(c_token)) {
  1389.             /* We have string specified - grab it. */
  1390.             quotel_str(str,c_token);
  1391.             c_token++;
  1392.         }
  1393.         if (!END_OF_COMMAND) {
  1394.             struct value a;
  1395.  
  1396.             /* We have x,y offsets specified */
  1397.             if (!equals(c_token,","))
  1398.                 *xpos = (int)real(const_express(&a));
  1399.             if (!END_OF_COMMAND && equals(c_token,",")) {
  1400.                 c_token++;
  1401.                 *ypos = (int)real(const_express(&a));
  1402.             }
  1403.         }
  1404.     }
  1405. }
  1406.  
  1407. /* process a 'set label' command */
  1408. /* set label {tag} {label_text} {at x,y} {pos} */
  1409. static void
  1410. set_label()
  1411. {
  1412.     struct value a;
  1413.     struct text_label *this_label = NULL;
  1414.     struct text_label *new_label = NULL;
  1415.     struct text_label *prev_label = NULL;
  1416.     double x, y, z;
  1417.     char text[MAX_LINE_LEN+1];
  1418.     enum JUSTIFY just;
  1419.     int tag;
  1420.     TBOOLEAN set_text, set_position, set_just;
  1421.  
  1422.     /* get tag */
  1423.     if (!END_OF_COMMAND 
  1424.        && !isstring(c_token) 
  1425.        && !equals(c_token, "at")
  1426.        && !equals(c_token, "left")
  1427.        && !equals(c_token, "center")
  1428.        && !equals(c_token, "centre")
  1429.        && !equals(c_token, "right")) {
  1430.        /* must be a tag expression! */
  1431.        tag = (int)real(const_express(&a));
  1432.        if (tag <= 0)
  1433.         int_error("tag must be > zero", c_token);
  1434.     } else
  1435.      tag = assign_label_tag(); /* default next tag */
  1436.      
  1437.     /* get text */
  1438.     if (!END_OF_COMMAND && isstring(c_token)) {
  1439.        /* get text */
  1440.        quotel_str(text, c_token);
  1441.        c_token++;
  1442.        set_text = TRUE;
  1443.     } else {
  1444.        text[0] = '\0';        /* default no text */
  1445.        set_text = FALSE;
  1446.     }
  1447.      
  1448.     /* get justification - what the heck, let him put it here */
  1449.     if (!END_OF_COMMAND && !equals(c_token, "at")) {
  1450.        if (almost_equals(c_token,"l$eft")) {
  1451.           just = LEFT;
  1452.        }
  1453.        else if (almost_equals(c_token,"c$entre")
  1454.               || almost_equals(c_token,"c$enter")) {
  1455.           just = CENTRE;
  1456.        }
  1457.        else if (almost_equals(c_token,"r$ight")) {
  1458.           just = RIGHT;
  1459.        }
  1460.        else
  1461.         int_error("bad syntax in set label", c_token);
  1462.        c_token++;
  1463.        set_just = TRUE;
  1464.     } else {
  1465.        just = LEFT;            /* default left justified */
  1466.        set_just = FALSE;
  1467.     } 
  1468.  
  1469.     /* get position */
  1470.     if (!END_OF_COMMAND && equals(c_token, "at")) {
  1471.        c_token++;
  1472.        if (END_OF_COMMAND)
  1473.         int_error("coordinates expected", c_token);
  1474.        /* get coordinates */
  1475.        x = real(const_express(&a));
  1476.        if (!equals(c_token,","))
  1477.         int_error("',' expected",c_token);
  1478.        c_token++;
  1479.        y = real(const_express(&a));
  1480.        if (equals(c_token,",")) {
  1481.         c_token++;
  1482.         z = real(const_express(&a));
  1483.        }
  1484.        else
  1485.             z = 0;
  1486.        set_position = TRUE;
  1487.     } else {
  1488.        x = y = z = 0;            /* default at origin */
  1489.        set_position = FALSE;
  1490.     }
  1491.  
  1492.     /* get justification */
  1493.     if (!END_OF_COMMAND) {
  1494.        if (set_just)
  1495.         int_error("only one justification is allowed", c_token);
  1496.        if (almost_equals(c_token,"l$eft")) {
  1497.           just = LEFT;
  1498.        }
  1499.        else if (almost_equals(c_token,"c$entre")
  1500.               || almost_equals(c_token,"c$enter")) {
  1501.           just = CENTRE;
  1502.        }
  1503.        else if (almost_equals(c_token,"r$ight")) {
  1504.           just = RIGHT;
  1505.        }
  1506.        else
  1507.         int_error("bad syntax in set label", c_token);
  1508.        c_token++;
  1509.        set_just = TRUE;
  1510.     } 
  1511.  
  1512.     if (!END_OF_COMMAND)
  1513.      int_error("extraenous or out-of-order arguments in set label", c_token);
  1514.  
  1515.     /* OK! add label */
  1516.     if (first_label != NULL) { /* skip to last label */
  1517.        for (this_label = first_label; this_label != NULL ; 
  1518.            prev_label = this_label, this_label = this_label->next)
  1519.         /* is this the label we want? */
  1520.         if (tag <= this_label->tag)
  1521.           break;
  1522.     }
  1523.     if (this_label != NULL && tag == this_label->tag) {
  1524.        /* changing the label */
  1525.        if (set_position) {
  1526.           this_label->x = x;
  1527.           this_label->y = y;
  1528.           this_label->z = z;
  1529.        }
  1530.        if (set_text)
  1531.         (void) strcpy(this_label->text, text);
  1532.        if (set_just)
  1533.         this_label->pos = just;
  1534.     } else {
  1535.        /* adding the label */
  1536.        new_label = (struct text_label *) 
  1537.         alloc ( (unsigned long) sizeof(struct text_label), "label");
  1538.        if (prev_label != NULL)
  1539.         prev_label->next = new_label; /* add it to end of list */
  1540.        else 
  1541.         first_label = new_label; /* make it start of list */
  1542.        new_label->tag = tag;
  1543.        new_label->next = this_label;
  1544.        new_label->x = x;
  1545.        new_label->y = y;
  1546.        new_label->z = z;
  1547.        (void) strcpy(new_label->text, text);
  1548.        new_label->pos = just;
  1549.     }
  1550. }
  1551.  
  1552. /* process 'set nolabel' command */
  1553. /* set nolabel {tag} */
  1554. static void
  1555. set_nolabel()
  1556. {
  1557.     struct value a;
  1558.     struct text_label *this_label;
  1559.     struct text_label *prev_label; 
  1560.     int tag;
  1561.  
  1562.     if (END_OF_COMMAND) {
  1563.        /* delete all labels */
  1564.        while (first_label != NULL)
  1565.         delete_label((struct text_label *)NULL,first_label);
  1566.     }
  1567.     else {
  1568.        /* get tag */
  1569.        tag = (int)real(const_express(&a));
  1570.        if (!END_OF_COMMAND)
  1571.         int_error("extraneous arguments to set nolabel", c_token);
  1572.        for (this_label = first_label, prev_label = NULL;
  1573.            this_label != NULL;
  1574.            prev_label = this_label, this_label = this_label->next) {
  1575.           if (this_label->tag == tag) {
  1576.              delete_label(prev_label,this_label);
  1577.              return;        /* exit, our job is done */
  1578.           }
  1579.        }
  1580.        int_error("label not found", c_token);
  1581.     }
  1582. }
  1583.  
  1584. /* assign a new label tag */
  1585. /* labels are kept sorted by tag number, so this is easy */
  1586. static int                /* the lowest unassigned tag number */
  1587. assign_label_tag()
  1588. {
  1589.     struct text_label *this_label;
  1590.     int last = 0;            /* previous tag value */
  1591.  
  1592.     for (this_label = first_label; this_label != NULL;
  1593.         this_label = this_label->next)
  1594.      if (this_label->tag == last+1)
  1595.        last++;
  1596.      else
  1597.        break;
  1598.     
  1599.     return (last+1);
  1600. }
  1601.  
  1602. /* delete label from linked list started by first_label.
  1603.  * called with pointers to the previous label (prev) and the 
  1604.  * label to delete (this).
  1605.  * If there is no previous label (the label to delete is
  1606.  * first_label) then call with prev = NULL.
  1607.  */
  1608. static void
  1609. delete_label(prev,this)
  1610.     struct text_label *prev, *this;
  1611. {
  1612.     if (this!=NULL)    {        /* there really is something to delete */
  1613.        if (prev!=NULL)        /* there is a previous label */
  1614.         prev->next = this->next; 
  1615.        else                /* this = first_label so change first_label */
  1616.         first_label = this->next;
  1617.        free((char *)this);
  1618.     }
  1619. }
  1620.  
  1621.  
  1622. /* process a 'set arrow' command */
  1623. /* set arrow {tag} {from x,y} {to x,y} {{no}head} */
  1624. static void
  1625. set_arrow()
  1626. {
  1627.     struct value a;
  1628.     struct arrow_def *this_arrow = NULL;
  1629.     struct arrow_def *new_arrow = NULL;
  1630.     struct arrow_def *prev_arrow = NULL;
  1631.     double sx, sy, sz;
  1632.     double ex, ey, ez;
  1633.     int tag;
  1634.     TBOOLEAN set_start, set_end, head = 1;
  1635.  
  1636.     /* get tag */
  1637.     if (!END_OF_COMMAND 
  1638.        && !equals(c_token, "from")
  1639.        && !equals(c_token, "to")) {
  1640.        /* must be a tag expression! */
  1641.        tag = (int)real(const_express(&a));
  1642.        if (tag <= 0)
  1643.         int_error("tag must be > zero", c_token);
  1644.     } else
  1645.      tag = assign_arrow_tag(); /* default next tag */
  1646.      
  1647.     /* get start position */
  1648.     if (!END_OF_COMMAND && equals(c_token, "from")) {
  1649.        c_token++;
  1650.        if (END_OF_COMMAND)
  1651.         int_error("start coordinates expected", c_token);
  1652.        /* get coordinates */
  1653.        sx = real(const_express(&a));
  1654.        if (!equals(c_token,","))
  1655.         int_error("',' expected",c_token);
  1656.        c_token++;
  1657.        sy = real(const_express(&a));
  1658.        if (equals(c_token,",")) {
  1659.         c_token++;
  1660.         sz = real(const_express(&a));
  1661.        }
  1662.        else
  1663.            sz = 0;
  1664.        set_start = TRUE;
  1665.     } else {
  1666.        sx = sy = sz = 0;            /* default at origin */
  1667.        set_start = FALSE;
  1668.     }
  1669.  
  1670.     /* get end position */
  1671.     if (!END_OF_COMMAND && equals(c_token, "to")) {
  1672.        c_token++;
  1673.        if (END_OF_COMMAND)
  1674.         int_error("end coordinates expected", c_token);
  1675.        /* get coordinates */
  1676.        ex = real(const_express(&a));
  1677.        if (!equals(c_token,","))
  1678.         int_error("',' expected",c_token);
  1679.        c_token++;
  1680.        ey = real(const_express(&a));
  1681.        if (equals(c_token,",")) {
  1682.         c_token++;
  1683.         ez = real(const_express(&a));
  1684.        }
  1685.        else
  1686.         ez = 0;
  1687.        set_end = TRUE;
  1688.     } else {
  1689.        ex = ey = ez = 0;            /* default at origin */
  1690.        set_end = FALSE;
  1691.     }
  1692.  
  1693.     /* get start position - what the heck, either order is ok */
  1694.     if (!END_OF_COMMAND && equals(c_token, "from")) {
  1695.        if (set_start)
  1696.         int_error("only one 'from' is allowed", c_token);
  1697.        c_token++;
  1698.        if (END_OF_COMMAND)
  1699.         int_error("start coordinates expected", c_token);
  1700.        /* get coordinates */
  1701.        sx = real(const_express(&a));
  1702.        if (!equals(c_token,","))
  1703.         int_error("',' expected",c_token);
  1704.        c_token++;
  1705.        sy = real(const_express(&a));
  1706.        if (equals(c_token,",")) {
  1707.         c_token++;
  1708.         sz = real(const_express(&a));
  1709.        }
  1710.        else
  1711.            sz = 0;
  1712.        set_start = TRUE;
  1713.     }
  1714.  
  1715.     if (!END_OF_COMMAND && equals(c_token, "nohead")) {
  1716.        c_token++;
  1717.            head = 0;
  1718.     }
  1719.  
  1720.     if (!END_OF_COMMAND && equals(c_token, "head")) {
  1721.        c_token++;
  1722.            head = 1;
  1723.     }
  1724.  
  1725.     if (!END_OF_COMMAND)
  1726.      int_error("extraneous or out-of-order arguments in set arrow", c_token);
  1727.  
  1728.     /* OK! add arrow */
  1729.     if (first_arrow != NULL) { /* skip to last arrow */
  1730.        for (this_arrow = first_arrow; this_arrow != NULL ; 
  1731.            prev_arrow = this_arrow, this_arrow = this_arrow->next)
  1732.         /* is this the arrow we want? */
  1733.         if (tag <= this_arrow->tag)
  1734.           break;
  1735.     }
  1736.     if (this_arrow != NULL && tag == this_arrow->tag) {
  1737.        /* changing the arrow */
  1738.        if (set_start) {
  1739.           this_arrow->sx = sx;
  1740.           this_arrow->sy = sy;
  1741.           this_arrow->sz = sz;
  1742.        }
  1743.        if (set_end) {
  1744.           this_arrow->ex = ex;
  1745.           this_arrow->ey = ey;
  1746.           this_arrow->ez = ez;
  1747.        }
  1748.        this_arrow->head = head;
  1749.     } else {
  1750.        /* adding the arrow */
  1751.        new_arrow = (struct arrow_def *) 
  1752.         alloc ( (unsigned long) sizeof(struct arrow_def), "arrow");
  1753.        if (prev_arrow != NULL)
  1754.         prev_arrow->next = new_arrow; /* add it to end of list */
  1755.        else 
  1756.         first_arrow = new_arrow; /* make it start of list */
  1757.        new_arrow->tag = tag;
  1758.        new_arrow->next = this_arrow;
  1759.        new_arrow->sx = sx;
  1760.        new_arrow->sy = sy;
  1761.        new_arrow->sz = sz;
  1762.        new_arrow->ex = ex;
  1763.        new_arrow->ey = ey;
  1764.        new_arrow->ez = ez;
  1765.        new_arrow->head = head;
  1766.     }
  1767. }
  1768.  
  1769. /* process 'set noarrow' command */
  1770. /* set noarrow {tag} */
  1771. static void
  1772. set_noarrow()
  1773. {
  1774.     struct value a;
  1775.     struct arrow_def *this_arrow;
  1776.     struct arrow_def *prev_arrow; 
  1777.     int tag;
  1778.  
  1779.     if (END_OF_COMMAND) {
  1780.        /* delete all arrows */
  1781.        while (first_arrow != NULL)
  1782.         delete_arrow((struct arrow_def *)NULL,first_arrow);
  1783.     }
  1784.     else {
  1785.        /* get tag */
  1786.        tag = (int)real(const_express(&a));
  1787.        if (!END_OF_COMMAND)
  1788.         int_error("extraneous arguments to set noarrow", c_token);
  1789.        for (this_arrow = first_arrow, prev_arrow = NULL;
  1790.            this_arrow != NULL;
  1791.            prev_arrow = this_arrow, this_arrow = this_arrow->next) {
  1792.           if (this_arrow->tag == tag) {
  1793.              delete_arrow(prev_arrow,this_arrow);
  1794.              return;        /* exit, our job is done */
  1795.           }
  1796.        }
  1797.        int_error("arrow not found", c_token);
  1798.     }
  1799. }
  1800.  
  1801. /* assign a new arrow tag */
  1802. /* arrows are kept sorted by tag number, so this is easy */
  1803. static int                /* the lowest unassigned tag number */
  1804. assign_arrow_tag()
  1805. {
  1806.     struct arrow_def *this_arrow;
  1807.     int last = 0;            /* previous tag value */
  1808.  
  1809.     for (this_arrow = first_arrow; this_arrow != NULL;
  1810.         this_arrow = this_arrow->next)
  1811.      if (this_arrow->tag == last+1)
  1812.        last++;
  1813.      else
  1814.        break;
  1815.  
  1816.     return (last+1);
  1817. }
  1818.  
  1819. /* delete arrow from linked list started by first_arrow.
  1820.  * called with pointers to the previous arrow (prev) and the 
  1821.  * arrow to delete (this).
  1822.  * If there is no previous arrow (the arrow to delete is
  1823.  * first_arrow) then call with prev = NULL.
  1824.  */
  1825. static void
  1826. delete_arrow(prev,this)
  1827.     struct arrow_def *prev, *this;
  1828. {
  1829.     if (this!=NULL)    {        /* there really is something to delete */
  1830.        if (prev!=NULL)        /* there is a previous arrow */
  1831.         prev->next = this->next; 
  1832.        else                /* this = first_arrow so change first_arrow */
  1833.         first_arrow = this->next;
  1834.        free((char *)this);
  1835.     }
  1836. }
  1837.  
  1838.  
  1839. enum PLOT_STYLE            /* not static; used by command.c */
  1840. get_style()
  1841. {
  1842. register enum PLOT_STYLE ps;
  1843.  
  1844.     c_token++;
  1845.     if (almost_equals(c_token,"l$ines"))
  1846.         ps = LINES;
  1847.     else if (almost_equals(c_token,"i$mpulses"))
  1848.         ps = IMPULSES;
  1849.     else if (almost_equals(c_token,"p$oints"))
  1850.         ps = POINTSTYLE;
  1851.     else if (almost_equals(c_token,"linesp$oints"))
  1852.         ps = LINESPOINTS;
  1853.     else if (almost_equals(c_token,"d$ots"))
  1854.         ps = DOTS;
  1855.     else if (almost_equals(c_token,"e$rrorbars"))
  1856.         ps = ERRORBARS;
  1857.     else if (almost_equals(c_token,"b$oxes"))
  1858.         ps = BOXES;
  1859.     else if (almost_equals(c_token,"boxer$rorbars"))
  1860.         ps = BOXERROR;
  1861.     else if (almost_equals(c_token,"s$teps"))
  1862.         ps = STEPS;
  1863.     else
  1864.         int_error("expecting 'lines', 'points', 'linespoints', 'dots', 'impulses', \n\
  1865.         'errorbars', 'steps', 'boxes' or 'boxerrorbars'",c_token);
  1866.     c_token++;
  1867.     return(ps);
  1868. }
  1869.  
  1870. /* For set [xy]tics... command*/
  1871. static void
  1872. load_tics(tdef)
  1873.     struct ticdef *tdef;    /* change this ticdef */
  1874. {
  1875.     if (equals(c_token,"(")) { /* set : TIC_USER */
  1876.        c_token++;
  1877.        load_tic_user(tdef);
  1878.     } else {                /* series : TIC_SERIES */
  1879.        load_tic_series(tdef);
  1880.     }
  1881. }
  1882.  
  1883. /* load TIC_USER definition */
  1884. /* (tic[,tic]...)
  1885.  * where tic is ["string"] value
  1886.  * Left paren is already scanned off before entry.
  1887.  */
  1888. static void
  1889. load_tic_user(tdef)
  1890.     struct ticdef *tdef;
  1891. {
  1892.     struct ticmark *list = NULL; /* start of list */
  1893.     struct ticmark *last = NULL; /* end of list */
  1894.     struct ticmark *tic = NULL; /* new ticmark */
  1895.     char temp_string[MAX_LINE_LEN];
  1896.     struct value a;
  1897.  
  1898.     while (!END_OF_COMMAND) {
  1899.        /* parse a new ticmark */
  1900.        tic = (struct ticmark *)alloc((unsigned long)sizeof(struct ticmark), (char *)NULL);
  1901.        if (tic == (struct ticmark *)NULL) {
  1902.           free_marklist(list);
  1903.           int_error("out of memory for tic mark", c_token);
  1904.        }
  1905.  
  1906.        /* has a string with it? */
  1907.        if (isstring(c_token)) {
  1908.           quote_str(temp_string,c_token);
  1909.           tic->label = alloc((unsigned long)strlen(temp_string)+1, "tic label");
  1910.           (void) strcpy(tic->label, temp_string);
  1911.           c_token++;
  1912.        } else
  1913.         tic->label = NULL;
  1914.  
  1915.        /* in any case get the value */
  1916.        tic->position = real(const_express(&a));
  1917.        tic->next = NULL;
  1918.  
  1919.        /* append to list */
  1920.        if (list == NULL)
  1921.         last = list = tic;    /* new list */
  1922.        else {                /* append to list */
  1923.           last->next = tic;
  1924.           last = tic;
  1925.        }
  1926.  
  1927.        /* expect "," or ")" here */
  1928.        if (!END_OF_COMMAND && equals(c_token, ","))
  1929.         c_token++;        /* loop again */
  1930.        else
  1931.         break;            /* hopefully ")" */
  1932.     }
  1933.     
  1934.     if (END_OF_COMMAND || !equals(c_token, ")")) {
  1935.        free_marklist(list);
  1936.        int_error("expecting right parenthesis )", c_token);
  1937.     }
  1938.     c_token++;
  1939.     
  1940.     /* successful list */
  1941.     if (tdef->type == TIC_USER) {
  1942.        /* remove old list */
  1943.         /* VAX Optimiser was stuffing up following line. Turn Optimiser OFF */
  1944.        free_marklist(tdef->def.user);
  1945.        tdef->def.user = NULL;
  1946.     }
  1947.     tdef->type = TIC_USER;
  1948.     tdef->def.user = list;
  1949. }
  1950.  
  1951. static void
  1952. free_marklist(list)
  1953.     struct ticmark *list;
  1954. {
  1955.     register struct ticmark *freeable;
  1956.  
  1957.     while (list != NULL) {
  1958.        freeable = list;
  1959.        list = list->next;
  1960.        if (freeable->label != NULL)
  1961.         free( (char *)freeable->label );
  1962.        free( (char *)freeable );
  1963.     }
  1964. }
  1965.  
  1966. /* load TIC_SERIES definition */
  1967. /* start,incr[,end] */
  1968. static void
  1969. load_tic_series(tdef)
  1970.     struct ticdef *tdef;
  1971. {
  1972.     double start, incr, end;
  1973.     struct value a;
  1974.     int incr_token;
  1975.  
  1976.     start = real(const_express(&a));
  1977.     if (!equals(c_token, ","))
  1978.      int_error("expecting comma to separate start,incr", c_token);
  1979.     c_token++;
  1980.  
  1981.     incr_token = c_token;
  1982.     incr = real(const_express(&a));
  1983.  
  1984.     if (END_OF_COMMAND)
  1985.      end = VERYLARGE;
  1986.     else {
  1987.        if (!equals(c_token, ","))
  1988.         int_error("expecting comma to separate incr,end", c_token);
  1989.        c_token++;
  1990.  
  1991.        end = real(const_express(&a));
  1992.     }
  1993.     if (!END_OF_COMMAND)
  1994.      int_error("tic series is defined by start,increment[,end]", 
  1995.              c_token);
  1996.     
  1997.     if (start < end && incr <= 0)
  1998.      int_error("increment must be positive", incr_token);
  1999.     if (start > end && incr >= 0)
  2000.      int_error("increment must be negative", incr_token);
  2001.     if (start > end) {
  2002.        /* put in order */
  2003.         double numtics;
  2004.         numtics = floor( (end*(1+SIGNIF) - start)/incr );
  2005.         end = start;
  2006.         start = end + numtics*incr;
  2007.         incr = -incr;
  2008. /*
  2009.        double temp = start;
  2010.        start = end;
  2011.        end = temp;
  2012.        incr = -incr;
  2013.  */
  2014.     }
  2015.  
  2016.     if (tdef->type == TIC_USER) {
  2017.        /* remove old list */
  2018.         /* VAX Optimiser was stuffing up following line. Turn Optimiser OFF */
  2019.        free_marklist(tdef->def.user);
  2020.        tdef->def.user = NULL;
  2021.     }
  2022.     tdef->type = TIC_SERIES;
  2023.     tdef->def.series.start = start;
  2024.     tdef->def.series.incr = incr;
  2025.     tdef->def.series.end = end;
  2026. }
  2027.  
  2028. static void
  2029. load_offsets (a, b, c, d)
  2030. double *a,*b, *c, *d;
  2031. {
  2032. struct value t;
  2033.  
  2034.     *a = real (const_express(&t));  /* loff value */
  2035.     c_token++;
  2036.     if (equals(c_token,","))
  2037.         c_token++;
  2038.     if (END_OF_COMMAND) 
  2039.         return;
  2040.  
  2041.     *b = real (const_express(&t));  /* roff value */
  2042.     c_token++;
  2043.     if (equals(c_token,","))
  2044.         c_token++;
  2045.     if (END_OF_COMMAND) 
  2046.         return;
  2047.  
  2048.     *c = real (const_express(&t));  /* toff value */
  2049.     c_token++;
  2050.     if (equals(c_token,","))
  2051.         c_token++;
  2052.     if (END_OF_COMMAND) 
  2053.         return;
  2054.  
  2055.     *d = real (const_express(&t));  /* boff value */
  2056.     c_token++;
  2057. }
  2058.  
  2059.  
  2060. TBOOLEAN                    /* TRUE if a or b were changed */
  2061. load_range(a,b)            /* also used by command.c */
  2062. double *a,*b;
  2063. {
  2064. struct value t;
  2065. TBOOLEAN changed = FALSE;
  2066.  
  2067.     if (equals(c_token,"]"))
  2068.         return(FALSE);
  2069.     if (END_OF_COMMAND) {
  2070.         int_error("starting range value or ':' or 'to' expected",c_token);
  2071.     } else if (!equals(c_token,"to") && !equals(c_token,":"))  {
  2072.         *a = real(const_express(&t));
  2073.         changed = TRUE;
  2074.     }    
  2075.     if (!equals(c_token,"to") && !equals(c_token,":"))
  2076.         int_error("':' or keyword 'to' expected",c_token);
  2077.     c_token++;
  2078.     if (!equals(c_token,"]")) {
  2079.         *b = real(const_express(&t));
  2080.         changed = TRUE;
  2081.      }
  2082.      return(changed);
  2083. }
  2084.  
  2085.  
  2086.  
  2087. /******* The 'show' command *******/
  2088. void
  2089. show_command()
  2090. {
  2091.     static char GPFAR showmess[] = 
  2092.     "valid show options:  'action_table', 'all', 'angles', 'arrow', \n\
  2093.     'autoscale', 'border', 'boxwidth', 'clip', 'contour', 'data', \n\
  2094.     'dgrid3d', 'dummy', 'format', 'function', 'grid', 'hidden', 'key', \n\
  2095.     'label', 'logscale', 'mapping',  'offsets', 'output', 'plot', \n\
  2096.     'parametric', 'polar', 'rrange', 'samples', 'isosamples', 'view', \n\
  2097.     'size', 'terminal', 'tics', 'ticslevel', 'time', 'title', 'trange', \n\
  2098.     'urange', 'vrange', 'variables', 'version', \n\
  2099.     'xlabel', 'xrange', '{no}xtics', 'xmtics', 'xdtics', '{no}xzeroaxis',\n\
  2100.     'ylabel', 'yrange', '{no}ytics', 'ymtics', 'ydtics', '{no}yzeroaxis',\n\
  2101.      'zero', '{no}zeroaxis', 'zlabel', 'zrange', '{no}ztics',\n\
  2102.      'zmtics', 'zdtics'";
  2103.  
  2104.     c_token++;
  2105.  
  2106.     if (!show_one() && !show_two())
  2107.     int_error(showmess, c_token);
  2108.     screen_ok = FALSE;
  2109.     (void) putc('\n',stderr);
  2110. }
  2111.  
  2112. /* return TRUE if a command match, FALSE if not */
  2113. static TBOOLEAN
  2114. show_one()
  2115. {
  2116.     if (almost_equals(c_token,"ac$tion_table") ||
  2117.              equals(c_token,"at") ) {
  2118.         c_token++; 
  2119.         show_at();
  2120.         c_token++;
  2121.     }
  2122.     else if (almost_equals(c_token,"ar$row")) {
  2123.         struct value a;
  2124.         int tag = 0;
  2125.  
  2126.         c_token++;
  2127.         if (!END_OF_COMMAND) {
  2128.            tag = (int)real(const_express(&a));
  2129.            if (tag <= 0)
  2130.             int_error("tag must be > zero", c_token);
  2131.         }
  2132.  
  2133.         (void) putc('\n',stderr);
  2134.         show_arrow(tag);
  2135.     }
  2136.     else if (almost_equals(c_token,"au$toscale")) {
  2137.         (void) putc('\n',stderr);
  2138.         show_autoscale();
  2139.         c_token++;
  2140.     }
  2141.     else if (almost_equals(c_token,"bor$der")) {
  2142.         (void) putc('\n',stderr);
  2143.         show_border();
  2144.         c_token++;
  2145.     }
  2146.     else if (almost_equals(c_token,"box$width")) {
  2147.         (void) putc('\n',stderr);
  2148.         show_boxwidth();
  2149.         c_token++;
  2150.     }
  2151.     else if (almost_equals(c_token,"c$lip")) {
  2152.         (void) putc('\n',stderr);
  2153.         show_clip();
  2154.         c_token++;
  2155.     }
  2156.     else if (almost_equals(c_token,"ma$pping")) {
  2157.         (void) putc('\n',stderr);
  2158.         show_mapping();
  2159.         c_token++;
  2160.     }
  2161.     else if (almost_equals(c_token,"co$ntour")) {
  2162.         (void) putc('\n',stderr);
  2163.         show_contour();
  2164.         c_token++;
  2165.     }
  2166.     else if (almost_equals(c_token,"da$ta")) {
  2167.         c_token++;
  2168.         if (!almost_equals(c_token,"s$tyle"))
  2169.             int_error("expecting keyword 'style'",c_token);
  2170.         (void) putc('\n',stderr);
  2171.         show_style("data",data_style);
  2172.         c_token++;
  2173.     }
  2174.     else if (almost_equals(c_token,"dg$rid3d")) {
  2175.         (void) putc('\n',stderr);
  2176.         show_dgrid3d();
  2177.         c_token++;
  2178.     }
  2179.     else if (almost_equals(c_token,"du$mmy")) {
  2180.           (void) fprintf(stderr,"\n\tdummy variables are \"%s\" and \"%s\"\n",
  2181.                         dummy_var[0], dummy_var[1]);
  2182.         c_token++;
  2183.     }
  2184.     else if (almost_equals(c_token,"fo$rmat")) {
  2185.         show_format();
  2186.         c_token++;
  2187.     }
  2188.     else if (almost_equals(c_token,"fu$nctions")) {
  2189.         c_token++;
  2190.         if (almost_equals(c_token,"s$tyle"))  {
  2191.             (void) putc('\n',stderr);
  2192.             show_style("functions",func_style);
  2193.             c_token++;
  2194.         }
  2195.         else
  2196.             show_functions();
  2197.     }
  2198.     else if (almost_equals(c_token,"lo$gscale")) {
  2199.         (void) putc('\n',stderr);
  2200.         show_logscale();
  2201.         c_token++;
  2202.     }
  2203.     else if (almost_equals(c_token,"of$fsets")) {
  2204.         (void) putc('\n',stderr);
  2205.         show_offsets();
  2206.         c_token++;
  2207.     }
  2208.     else if (almost_equals(c_token,"o$utput")) {
  2209.         (void) putc('\n',stderr);
  2210.         show_output();
  2211.         c_token++;
  2212.     }
  2213.     else if (almost_equals(c_token,"tit$le")) {
  2214.         (void) putc('\n',stderr);
  2215.         show_title();
  2216.         c_token++;
  2217.     }
  2218.     else if (almost_equals(c_token,"xl$abel")) {
  2219.         (void) putc('\n',stderr);
  2220.         show_xlabel();
  2221.         c_token++;
  2222.     }
  2223.     else if (almost_equals(c_token,"yl$abel")) {
  2224.         (void) putc('\n',stderr);
  2225.         show_ylabel();
  2226.         c_token++;
  2227.     }
  2228.     else if (almost_equals(c_token,"zl$abel")) {
  2229.         (void) putc('\n',stderr);
  2230.         show_zlabel();
  2231.         c_token++;
  2232.     }
  2233.     else if (almost_equals(c_token,"xzero$axis")) {
  2234.         (void) putc('\n',stderr);
  2235.         show_xzeroaxis();
  2236.         c_token++;
  2237.     }
  2238.     else if (almost_equals(c_token,"yzero$axis")) {
  2239.         (void) putc('\n',stderr);
  2240.         show_yzeroaxis();
  2241.         c_token++;
  2242.     }
  2243.     else if (almost_equals(c_token,"zeroa$xis")) {
  2244.         (void) putc('\n',stderr);
  2245.         show_xzeroaxis();
  2246.         show_yzeroaxis();
  2247.         c_token++;
  2248.     }
  2249.     else if (almost_equals(c_token,"la$bel")) {
  2250.         struct value a;
  2251.         int tag = 0;
  2252.  
  2253.         c_token++;
  2254.         if (!END_OF_COMMAND) {
  2255.            tag = (int)real(const_express(&a));
  2256.            if (tag <= 0)
  2257.             int_error("tag must be > zero", c_token);
  2258.         }
  2259.  
  2260.         (void) putc('\n',stderr);
  2261.         show_label(tag);
  2262.     }
  2263.     else if (almost_equals(c_token,"g$rid")) {
  2264.         (void) putc('\n',stderr);
  2265.         show_grid();
  2266.         c_token++;
  2267.     }
  2268.     else if (almost_equals(c_token,"k$ey")) {
  2269.         (void) putc('\n',stderr);
  2270.         show_key();
  2271.         c_token++;
  2272.     }
  2273.     else
  2274.         return (FALSE);
  2275.     return TRUE;
  2276. }
  2277.  
  2278. /* return TRUE if a command match, FALSE if not */
  2279. static TBOOLEAN
  2280. show_two()
  2281. {
  2282.     if (almost_equals(c_token,"p$lot")) {
  2283.         (void) putc('\n',stderr);
  2284.         show_plot();
  2285.         c_token++;
  2286.     }
  2287.     else if (almost_equals(c_token,"par$ametric")) {
  2288.         (void) putc('\n',stderr);
  2289.         show_parametric();
  2290.         c_token++;
  2291.     }
  2292.     else if (almost_equals(c_token,"pol$ar")) {
  2293.         (void) putc('\n',stderr);
  2294.         show_polar();
  2295.         c_token++;
  2296.     }
  2297.     else if (almost_equals(c_token,"an$gles")) {
  2298.         (void) putc('\n',stderr);
  2299.         show_angles();
  2300.         c_token++;
  2301.     }
  2302.     else if (almost_equals(c_token,"ti$cs")) {
  2303.         (void) putc('\n',stderr);
  2304.         show_tics(TRUE,TRUE,TRUE);
  2305.         c_token++;
  2306.     }
  2307.     else if (almost_equals(c_token,"tim$e")) {
  2308.         (void) putc('\n',stderr);
  2309.         show_time();
  2310.         c_token++;
  2311.     }
  2312.     else if (almost_equals(c_token,"su$rface")) {
  2313.         (void) putc('\n',stderr);
  2314.         show_surface();
  2315.         c_token++;
  2316.     }
  2317.     else if (almost_equals(c_token,"hi$dden3d")) {
  2318.         (void) putc('\n',stderr);
  2319.         show_hidden3d();
  2320.         c_token++;
  2321.     }
  2322.      else if (almost_equals(c_token,"cla$bel")) {
  2323.          (void) putc('\n',stderr);
  2324.          show_label_contours();
  2325.          c_token++;
  2326.      }
  2327.     else if (almost_equals(c_token,"xti$cs")) {
  2328.         show_tics(TRUE,FALSE,FALSE);
  2329.         c_token++;
  2330.     }
  2331.     else if (almost_equals(c_token,"yti$cs")) {
  2332.         show_tics(FALSE,TRUE,FALSE);
  2333.         c_token++;
  2334.     }
  2335.     else if (almost_equals(c_token,"zti$cs")) {
  2336.         show_tics(FALSE,FALSE,TRUE);
  2337.         c_token++;
  2338.     }
  2339.     else if (almost_equals(c_token,"sa$mples")) {
  2340.         (void) putc('\n',stderr);
  2341.         show_samples();
  2342.         c_token++;
  2343.     }
  2344.     else if (almost_equals(c_token,"isosa$mples")) {
  2345.         (void) putc('\n',stderr);
  2346.         show_isosamples();
  2347.         c_token++;
  2348.     }
  2349.     else if (almost_equals(c_token,"si$ze")) {
  2350.         (void) putc('\n',stderr);
  2351.         show_size();
  2352.         c_token++;
  2353.     }
  2354.     else if (almost_equals(c_token,"t$erminal")) {
  2355.         (void) putc('\n',stderr);
  2356.         show_term();
  2357.         c_token++;
  2358.     }
  2359.     else if (almost_equals(c_token,"rr$ange")) {
  2360.         (void) putc('\n',stderr);
  2361.         show_range('r',rmin,rmax);
  2362.         c_token++;
  2363.     }
  2364.     else if (almost_equals(c_token,"tr$ange")) {
  2365.         (void) putc('\n',stderr);
  2366.         show_range('t',tmin,tmax);
  2367.         c_token++;
  2368.     }
  2369.     else if (almost_equals(c_token,"ur$ange")) {
  2370.         (void) putc('\n',stderr);
  2371.         show_range('u',umin,umax);
  2372.         c_token++;
  2373.     }
  2374.     else if (almost_equals(c_token,"vi$ew")) {
  2375.         (void) putc('\n',stderr);
  2376.         show_view();
  2377.         c_token++;
  2378.     }
  2379.     else if (almost_equals(c_token,"vr$ange")) {
  2380.         (void) putc('\n',stderr);
  2381.         show_range('v',vmin,vmax);
  2382.         c_token++;
  2383.     }
  2384.     else if (almost_equals(c_token,"v$ariables")) {
  2385.         show_variables();
  2386.         c_token++;
  2387.     }
  2388.     else if (almost_equals(c_token,"ve$rsion")) {
  2389.         show_version();
  2390.         c_token++;
  2391.     }
  2392.     else if (almost_equals(c_token,"xr$ange")) {
  2393.         (void) putc('\n',stderr);
  2394.         show_range('x',xmin,xmax);
  2395.         c_token++;
  2396.     }
  2397.     else if (almost_equals(c_token,"yr$ange")) {
  2398.         (void) putc('\n',stderr);
  2399.         show_range('y',ymin,ymax);
  2400.         c_token++;
  2401.     }
  2402.     else if (almost_equals(c_token,"zr$ange")) {
  2403.         (void) putc('\n',stderr);
  2404.         show_range('z',zmin,zmax);
  2405.         c_token++;
  2406.     }
  2407.     else if (almost_equals(c_token,"z$ero")) {
  2408.         (void) putc('\n',stderr);
  2409.         show_zero();
  2410.         c_token++;
  2411.     }
  2412.     else if (almost_equals(c_token,"a$ll")) {
  2413.         c_token++;
  2414.         show_version();
  2415.         show_autoscale();
  2416.         show_border();
  2417.         show_boxwidth();
  2418.         show_clip();
  2419.         show_contour();
  2420.         show_dgrid3d();
  2421.         show_mapping();
  2422.           (void) fprintf(stderr,"\tdummy variables are \"%s\" and \"%s\"\n",
  2423.                         dummy_var[0], dummy_var[1]);
  2424.         show_format();
  2425.         show_style("data",data_style);
  2426.         show_style("functions",func_style);
  2427.         show_grid();
  2428.         show_label(0);
  2429.         show_arrow(0);
  2430.         show_key();
  2431.         show_logscale();
  2432.         show_offsets();
  2433.         show_output();
  2434.         show_parametric();
  2435.         show_polar();
  2436.         show_angles();
  2437.         show_samples();
  2438.         show_isosamples();
  2439.         show_view();
  2440.         show_surface();
  2441. #ifndef LITE
  2442.         show_hidden3d();
  2443. #endif
  2444.         show_size();
  2445.         show_term();
  2446.         show_tics(TRUE,TRUE,TRUE);
  2447.         show_time();
  2448.         if (parametric)
  2449.             if (!is_3d_plot)
  2450.                 show_range('t',tmin,tmax);
  2451.             else {
  2452.                 show_range('u',umin,umax);
  2453.                 show_range('v',vmin,vmax);
  2454.             }
  2455.         if (polar)
  2456.           show_range('r',rmin,rmax);
  2457.         show_range('x',xmin,xmax);
  2458.         show_range('y',ymin,ymax);
  2459.         show_range('z',zmin,zmax);
  2460.         show_title();
  2461.         show_xlabel();
  2462.         show_ylabel();
  2463.         show_zlabel();
  2464.         show_zero();
  2465.         show_plot();
  2466.         show_variables();
  2467.         show_functions();
  2468.         c_token++;
  2469.     }
  2470.     else
  2471.         return (FALSE);
  2472.     return (TRUE);
  2473. }
  2474.  
  2475.  
  2476. /*********** support functions for 'show'  **********/
  2477. static void
  2478. show_style(name,style)
  2479. char name[];
  2480. enum PLOT_STYLE style;
  2481. {
  2482.     fprintf(stderr,"\t%s are plotted with ",name);
  2483.     switch (style) {
  2484.         case LINES: fprintf(stderr,"lines\n"); break;
  2485.         case POINTSTYLE: fprintf(stderr,"points\n"); break;
  2486.         case IMPULSES: fprintf(stderr,"impulses\n"); break;
  2487.         case LINESPOINTS: fprintf(stderr,"linespoints\n"); break;
  2488.         case DOTS: fprintf(stderr,"dots\n"); break;
  2489.         case ERRORBARS: fprintf(stderr,"errorbars\n"); break;
  2490.         case BOXES: fprintf(stderr,"boxes\n"); break;
  2491.         case BOXERROR: fprintf(stderr,"boxerrorbars\n"); break;
  2492.         case STEPS: fprintf(stderr,"steps\n"); break;
  2493.     }
  2494. }
  2495.  
  2496. static void
  2497. show_boxwidth()
  2498. {
  2499.     if (boxwidth<0.0)
  2500.         fprintf(stderr,"\tboxwidth is auto\n");
  2501.     else
  2502.         fprintf(stderr,"\tboxwidth is %g\n",boxwidth);
  2503. }
  2504. static void
  2505. show_dgrid3d()
  2506. {
  2507.     if (dgrid3d)
  2508.         fprintf(stderr,"\tdata grid3d is enabled for mesh of size %dx%d, norm=%d\n",
  2509.             dgrid3d_row_fineness,
  2510.             dgrid3d_col_fineness,
  2511.             dgrid3d_norm_value);
  2512.     else
  2513.         fprintf(stderr,"\tdata grid3d is disabled\n");
  2514. }
  2515.  
  2516. static void
  2517. show_range(name,min,max)
  2518. char name;
  2519. double min,max;
  2520. {
  2521.     fprintf(stderr,"\t%crange is [%g : %g]\n",name,min,max);
  2522. }
  2523.  
  2524. static void
  2525. show_zero()
  2526. {
  2527.     fprintf(stderr,"\tzero is %g\n",zero);
  2528. }
  2529.  
  2530. static void
  2531. show_offsets()
  2532. {
  2533.     fprintf(stderr,"\toffsets are %g, %g, %g, %g\n",loff,roff,toff,boff);
  2534. }
  2535.  
  2536. static void
  2537. show_border()
  2538. {
  2539.     fprintf(stderr,"\tborder is %sdrawn\n", draw_border ? "" : "not ");
  2540. }
  2541.  
  2542. static void
  2543. show_output()
  2544. {
  2545.     fprintf(stderr,"\toutput is sent to %s\n",outstr);
  2546. }
  2547.  
  2548. static void
  2549. show_samples()
  2550. {
  2551.     fprintf(stderr,"\tsampling rate is %d, %d\n",samples_1, samples_2);
  2552. }
  2553.  
  2554. static void
  2555. show_isosamples()
  2556. {
  2557.     fprintf(stderr,"\tiso sampling rate is %d, %d\n",
  2558.         iso_samples_1, iso_samples_2);
  2559. }
  2560.  
  2561. static void
  2562. show_surface()
  2563. {
  2564.     fprintf(stderr,"\tsurface is %sdrawn\n", draw_surface ? "" : "not ");
  2565. }
  2566.  
  2567. static void
  2568. show_hidden3d()
  2569. {
  2570. #ifdef LITE
  2571.     printf(" Hidden Line Removal Not Supported in LITE version\n");
  2572. #else
  2573.     fprintf(stderr,"\thidden surface is %s\n", hidden3d ? "removed" : "drawn");
  2574. #endif /* LITE */
  2575. }
  2576.  
  2577. static void
  2578. show_label_contours()
  2579. {
  2580.     fprintf(stderr,"\tcontour line types are %s\n", label_contours ? "varied & labeled" : "all the same");
  2581. }
  2582.  
  2583. static void
  2584. show_view()
  2585. {
  2586.     fprintf(stderr,"\tview is %g rot_x, %g rot_z, %g scale, %g scale_z\n",
  2587.         surface_rot_x, surface_rot_z, surface_scale, surface_zscale);
  2588. }
  2589.  
  2590. static void
  2591. show_size()
  2592. {
  2593.     fprintf(stderr,"\tsize is scaled by %g,%g\n",xsize,ysize);
  2594. }
  2595.  
  2596. static void
  2597. show_title()
  2598. {
  2599.     fprintf(stderr,"\ttitle is \"%s\", offset at %d, %d\n",
  2600.         title,title_xoffset,title_yoffset);
  2601. }
  2602.  
  2603. static void
  2604. show_xlabel()
  2605. {
  2606.     fprintf(stderr,"\txlabel is \"%s\", offset at %d, %d\n",
  2607.         xlabel,xlabel_xoffset,xlabel_yoffset);
  2608. }
  2609.  
  2610. static void
  2611. show_ylabel()
  2612. {
  2613.     fprintf(stderr,"\tylabel is \"%s\", offset at %d, %d\n",
  2614.         ylabel,ylabel_xoffset,ylabel_yoffset);
  2615. }
  2616. static void
  2617. show_zlabel()
  2618. {
  2619.     fprintf(stderr,"\tzlabel is \"%s\", offset at %d, %d\n",
  2620.         zlabel,zlabel_xoffset,zlabel_yoffset);
  2621. }
  2622.  
  2623. static void
  2624. show_xzeroaxis()
  2625. {
  2626.     fprintf(stderr,"\txzeroaxis is %s\n",(xzeroaxis)? "ON" : "OFF");
  2627. }
  2628.  
  2629. static void
  2630. show_yzeroaxis()
  2631. {
  2632.     fprintf(stderr,"\tyzeroaxis is %s\n",(yzeroaxis)? "ON" : "OFF");
  2633. }
  2634.  
  2635. static void
  2636. show_label(tag)
  2637.     int tag;                /* 0 means show all */
  2638. {
  2639.     struct text_label *this_label;
  2640.     TBOOLEAN showed = FALSE;
  2641.  
  2642.     for (this_label = first_label; this_label != NULL;
  2643.         this_label = this_label->next) {
  2644.        if (tag == 0 || tag == this_label->tag) {
  2645.           showed = TRUE;
  2646.           fprintf(stderr,"\tlabel %d \"%s\" at %g,%g,%g ",
  2647.                 this_label->tag, this_label->text, 
  2648.                 this_label->x, this_label->y, this_label->z);
  2649.           switch(this_label->pos) {
  2650.              case LEFT : {
  2651.                 fprintf(stderr,"left");
  2652.                 break;
  2653.              }
  2654.              case CENTRE : {
  2655.                 fprintf(stderr,"centre");
  2656.                 break;
  2657.              }
  2658.              case RIGHT : {
  2659.                 fprintf(stderr,"right");
  2660.                 break;
  2661.              }
  2662.           }
  2663.           fputc('\n',stderr);
  2664.        }
  2665.     }
  2666.     if (tag > 0 && !showed)
  2667.      int_error("label not found", c_token);
  2668. }
  2669.  
  2670. static void
  2671. show_arrow(tag)
  2672.     int tag;                /* 0 means show all */
  2673. {
  2674.     struct arrow_def *this_arrow;
  2675.     TBOOLEAN showed = FALSE;
  2676.  
  2677.     for (this_arrow = first_arrow; this_arrow != NULL;
  2678.         this_arrow = this_arrow->next) {
  2679.        if (tag == 0 || tag == this_arrow->tag) {
  2680.           showed = TRUE;
  2681.           fprintf(stderr,"\tarrow %d from %g,%g,%g to %g,%g,%g%s\n",
  2682.                 this_arrow->tag, 
  2683.                 this_arrow->sx, this_arrow->sy, this_arrow->sz,
  2684.                 this_arrow->ex, this_arrow->ey, this_arrow->ez,
  2685.                 this_arrow->head ? "" : " (nohead)");
  2686.        }
  2687.     }
  2688.     if (tag > 0 && !showed)
  2689.      int_error("arrow not found", c_token);
  2690. }
  2691.  
  2692. static void
  2693. show_grid()
  2694. {
  2695.     fprintf(stderr,"\tgrid is %s\n",(grid)? "ON" : "OFF");
  2696. }
  2697.  
  2698. static void
  2699. show_key()
  2700. {
  2701.     switch (key) {
  2702.         case -1 : 
  2703.             fprintf(stderr,"\tkey is ON\n");
  2704.             break;
  2705.         case 0 :
  2706.             fprintf(stderr,"\tkey is OFF\n");
  2707.             break;
  2708.         case 1 :
  2709.             fprintf(stderr,"\tkey is at %g,%g,%g\n",key_x,key_y,key_z);
  2710.             break;
  2711.     }
  2712. }
  2713.  
  2714. static void
  2715. show_parametric()
  2716. {
  2717.     fprintf(stderr,"\tparametric is %s\n",(parametric)? "ON" : "OFF");
  2718. }
  2719.  
  2720. static void
  2721. show_polar()
  2722. {
  2723.     fprintf(stderr,"\tpolar is %s\n",(polar)? "ON" : "OFF");
  2724. }
  2725.  
  2726. static void
  2727. show_angles()
  2728. {
  2729.     fprintf(stderr,"\tAngles are in ");
  2730.     switch (angles_format) {
  2731.         case ANGLES_RADIANS:
  2732.             fprintf(stderr, "radians\n");
  2733.         break;
  2734.         case ANGLES_DEGREES:
  2735.             fprintf(stderr, "degrees\n");
  2736.         break;
  2737.     }
  2738. }
  2739.  
  2740.  
  2741. static void
  2742. show_tics(showx, showy, showz)
  2743.     TBOOLEAN showx, showy, showz;
  2744. {
  2745.     fprintf(stderr,"\ttics are %s, ",(tic_in)? "IN" : "OUT");
  2746.     fprintf(stderr,"\tticslevel is %g\n",ticslevel);
  2747.  
  2748.     if (showx)
  2749.      show_ticdef(xtics, 'x', &xticdef);
  2750.     if (showy)
  2751.      show_ticdef(ytics, 'y', &yticdef);
  2752.     if (showz)
  2753.      show_ticdef(ztics, 'z', &zticdef);
  2754.     screen_ok = FALSE;
  2755. }
  2756.  
  2757. /* called by show_tics */
  2758. static void
  2759. show_ticdef(tics, axis, tdef)
  2760.     TBOOLEAN tics;            /* xtics ytics or ztics */
  2761.     char axis;            /* 'x' 'y' or 'z' */
  2762.     struct ticdef *tdef;    /* xticdef yticdef or zticdef */
  2763. {
  2764.     register struct ticmark *t;
  2765.  
  2766.     fprintf(stderr, "\t%c-axis tic labelling is ", axis);
  2767.     if (!tics) {
  2768.        fprintf(stderr, "OFF\n");
  2769.        return;
  2770.     }
  2771.  
  2772.     switch(tdef->type) {
  2773.        case TIC_COMPUTED: {
  2774.           fprintf(stderr, "computed automatically\n");
  2775.           break;
  2776.        }
  2777.         case TIC_MONTH: {
  2778.         fprintf(stderr, "Months computed automatically\n");
  2779.         break;
  2780.        }
  2781.         case TIC_DAY:{
  2782.         fprintf(stderr, "Days computed automatically\n");
  2783.         }
  2784.        case TIC_SERIES: {
  2785.           if (tdef->def.series.end == VERYLARGE)
  2786.             fprintf(stderr, "series from %g by %g\n", 
  2787.                   tdef->def.series.start, tdef->def.series.incr);
  2788.           else
  2789.             fprintf(stderr, "series from %g by %g until %g\n", 
  2790.                   tdef->def.series.start, tdef->def.series.incr, 
  2791.                   tdef->def.series.end);
  2792.           break;
  2793.        }
  2794.        case TIC_USER: {
  2795.           fprintf(stderr, "list (");
  2796.           for (t = tdef->def.user; t != NULL; t=t->next) {
  2797.              if (t->label)
  2798.                fprintf(stderr, "\"%s\" ", t->label);
  2799.              if (t->next)
  2800.                fprintf(stderr, "%g, ", t->position);
  2801.              else
  2802.                fprintf(stderr, "%g", t->position);
  2803.           }
  2804.           fprintf(stderr, ")\n");
  2805.           break;
  2806.        }
  2807.        default: {
  2808.           int_error("unknown ticdef type in show_ticdef()", NO_CARET);
  2809.           /* NOTREACHED */
  2810.        }
  2811.     }
  2812. }
  2813.  
  2814. static void
  2815. show_time()
  2816. {
  2817.     fprintf(stderr,"\ttime is %s, offset at %d, %d\n",
  2818.         (timedate)? "ON" : "OFF",
  2819.         time_xoffset,time_yoffset);
  2820. }
  2821.  
  2822. static void
  2823. show_term()
  2824. {
  2825.     fprintf(stderr,"\tterminal type is %s %s\n",
  2826.         term_tbl[term].name, term_options);
  2827. }
  2828.  
  2829. static void
  2830. show_plot()
  2831. {
  2832.     fprintf(stderr,"\tlast plot command was: %s\n",replot_line);
  2833. }
  2834.  
  2835. static void
  2836. show_autoscale()
  2837. {
  2838.     fprintf(stderr,"\tautoscaling is ");
  2839.     if (parametric)
  2840.         if (is_3d_plot)
  2841.             fprintf(stderr,"\tt: %s, ",(autoscale_t)? "ON" : "OFF");
  2842.         else
  2843.             fprintf(stderr,"\tu: %s, v: %s, ",
  2844.                         (autoscale_u)? "ON" : "OFF",
  2845.                         (autoscale_v)? "ON" : "OFF");
  2846.     else fprintf(stderr,"\t");
  2847.  
  2848.     if (polar) fprintf(stderr,"r: %s, ",(autoscale_r)? "ON" : "OFF");
  2849.     fprintf(stderr,"x: %s, ",(autoscale_x)? "ON" : "OFF");
  2850.     fprintf(stderr,"y: %s, ",(autoscale_y)? "ON" : "OFF");
  2851.     fprintf(stderr,"z: %s\n",(autoscale_z)? "ON" : "OFF");
  2852. }
  2853.  
  2854. static void
  2855. show_clip()
  2856. {
  2857.     fprintf(stderr,"\tpoint clip is %s\n",(clip_points)? "ON" : "OFF");
  2858.  
  2859.     if (clip_lines1)
  2860.       fprintf(stderr,
  2861.          "\tdrawing and clipping lines between inrange and outrange points\n");
  2862.     else
  2863.       fprintf(stderr,
  2864.          "\tnot drawing lines between inrange and outrange points\n");
  2865.  
  2866.     if (clip_lines2)
  2867.       fprintf(stderr,
  2868.          "\tdrawing and clipping lines between two outrange points\n");
  2869.     else
  2870.       fprintf(stderr,
  2871.          "\tnot drawing lines between two outrange points\n");
  2872. }
  2873.  
  2874. static void
  2875. show_mapping()
  2876. {
  2877.     fprintf(stderr,"\tmapping for 3-d data is ");
  2878.  
  2879.     switch (mapping3d) {
  2880.         case MAP3D_CARTESIAN:
  2881.             fprintf(stderr,"cartesian\n");
  2882.             break;
  2883.         case MAP3D_SPHERICAL:
  2884.             fprintf(stderr,"spherical\n");
  2885.             break;
  2886.         case MAP3D_CYLINDRICAL:
  2887.             fprintf(stderr,"cylindrical\n");
  2888.             break;
  2889.     }
  2890. }
  2891.  
  2892. static void
  2893. show_contour()
  2894. {
  2895.     fprintf(stderr,"\tcontour for surfaces are %s",
  2896.         (draw_contour)? "drawn" : "not drawn\n");
  2897.  
  2898.     if (draw_contour) {
  2899.             fprintf(stderr, " in %d levels on ", contour_levels);
  2900.         switch (draw_contour) {
  2901.             case CONTOUR_BASE:
  2902.                 fprintf(stderr,"grid base\n");
  2903.                 break;
  2904.             case CONTOUR_SRF:
  2905.                 fprintf(stderr,"surface\n");
  2906.                 break;
  2907.             case CONTOUR_BOTH:
  2908.                 fprintf(stderr,"grid base and surface\n");
  2909.                 break;
  2910.         }
  2911.         switch (contour_kind) {
  2912.             case CONTOUR_KIND_LINEAR:
  2913.                 fprintf(stderr,"\t\tas linear segments\n");
  2914.                 break;
  2915.             case CONTOUR_KIND_CUBIC_SPL:
  2916.                 fprintf(stderr,"\t\tas cubic spline interpolation segments with %d pts\n",
  2917.                     contour_pts);
  2918.                 break;
  2919.             case CONTOUR_KIND_BSPLINE:
  2920.                 fprintf(stderr,"\t\tas bspline approximation segments of order %d with %d pts\n",
  2921.                     contour_order, contour_pts);
  2922.                 break;
  2923.         }
  2924.         switch (levels_kind) {
  2925.             int i;
  2926.             case LEVELS_AUTO:
  2927.                 fprintf(stderr,"\t\t%d automatic levels\n", contour_levels);
  2928.                 break;
  2929.             case LEVELS_DISCRETE:
  2930.                 fprintf(stderr,"\t\t%d discrete levels at ", contour_levels);
  2931.                         fprintf(stderr, "%g", levels_list[0]);
  2932.                 for(i = 1; i < contour_levels; i++)
  2933.                     fprintf(stderr,",%g ", levels_list[i]);
  2934.                 fprintf(stderr,"\n");
  2935.                 break;
  2936.             case LEVELS_INCREMENTAL:
  2937.                 fprintf(stderr,"\t\t%d incremental levels starting at %g, step %g, end %g\n",
  2938.                     contour_levels, levels_list[0], levels_list[1],
  2939.                     levels_list[0]+contour_levels*levels_list[1]);
  2940.                 break;
  2941.         }
  2942.         fprintf(stderr,"\t\tcontour line types are %s\n", label_contours ? "varied" : "all the same");
  2943.     }
  2944. }
  2945.  
  2946. static void
  2947. show_format()
  2948. {
  2949.     fprintf(stderr, "\ttic format is x-axis: \"%s\", y-axis: \"%s\", z-axis: \"%s\"\n",
  2950.         xformat, yformat, zformat);
  2951. }
  2952.  
  2953. static void
  2954. show_logscale()
  2955. {
  2956.     if (is_log_x) {
  2957.         fprintf(stderr,"\tlogscaling x (base %g)", base_log_x);
  2958.         if (is_log_y && is_log_z)
  2959.             fprintf(stderr,", y (base %g) and z (base %g)\n",
  2960.                 base_log_y, base_log_z);
  2961.         else if (is_log_y)
  2962.             fprintf(stderr," and y (base %g)\n", base_log_y);
  2963.         else if (is_log_z)
  2964.             fprintf(stderr," and z (base %g)\n", base_log_z);
  2965.         else
  2966.             fprintf(stderr," only\n");
  2967.     } else if (is_log_y) {
  2968.         fprintf(stderr,"\tlogscaling y (base %g)", base_log_y);
  2969.         if (is_log_z)
  2970.             fprintf(stderr," and z (base %g)\n", base_log_z);
  2971.         else
  2972.             fprintf(stderr," only\n");
  2973.     } else if (is_log_z) {
  2974.         fprintf(stderr,"\tlogscaling z (base %g) only\n", base_log_z);
  2975.     } else {
  2976.         fprintf(stderr,"\tno logscaling\n");
  2977.     }
  2978. }
  2979.  
  2980. static void
  2981. show_variables()
  2982. {
  2983. register struct udvt_entry *udv = first_udv;
  2984. int len;
  2985.  
  2986.     fprintf(stderr,"\n\tVariables:\n");
  2987.     while (udv) {
  2988.          len = instring(udv->udv_name, ' ');
  2989.         fprintf(stderr,"\t%-*s ",len,udv->udv_name);
  2990.         if (udv->udv_undef)
  2991.             fputs("is undefined\n",stderr);
  2992.         else {
  2993.             fputs("= ",stderr);
  2994.             disp_value(stderr,&(udv->udv_value));
  2995.             (void) putc('\n',stderr);
  2996.         }
  2997.         udv = udv->next_udv;
  2998.     }
  2999. }
  3000.  
  3001. char *authors[] = {"Thomas Williams","Colin Kelley"}; /* primary */
  3002. void                /* used by plot.c */
  3003. show_version()
  3004. {
  3005. extern char version[];
  3006. extern char patchlevel[];
  3007. extern char date[];
  3008. extern char copyright[];
  3009. extern char bug_email[];
  3010. extern char help_email[];
  3011. int x;
  3012. long time();
  3013.  
  3014.     x = time((long *)NULL) & 1;
  3015.     fprintf(stderr,"\n\t%s\n\t%sversion %s\n",
  3016.         PROGRAM, OS, version); 
  3017.     fprintf(stderr,"\tpatchlevel %s\n",patchlevel);
  3018.      fprintf(stderr, "\tlast modified %s\n", date);
  3019.     fprintf(stderr,"\n\t%s   %s, %s\n", copyright,authors[x],authors[1-x]);
  3020.     fprintf(stderr, "\n\tSend comments and requests for help to %s", help_email);
  3021.     fprintf(stderr, "\n\tSend bugs, suggestions and mods to %s\n", bug_email);
  3022. }
  3023.